Skip to content

Commit

Permalink
Merge pull request #126 from CogStack/more-search-improvements
Browse files Browse the repository at this point in the history
More search improvements
  • Loading branch information
tomolopolis authored Mar 3, 2023
2 parents 5355a6b + 3d84b5e commit 3d544e6
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 40 deletions.
2 changes: 1 addition & 1 deletion webapp/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.9
FROM python:3.10

# Update and upgrade everything
RUN apt-get -y update && \
Expand Down
1 change: 1 addition & 0 deletions webapp/api/api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

_dt_fmt = '%Y-%m-%d %H:%M:%S.%f'


def reset_project(modeladmin, request, queryset):
if not request.user.is_staff:
raise PermissionDenied
Expand Down
46 changes: 30 additions & 16 deletions webapp/api/api/solr_utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json
import logging
import re
from typing import List
from typing import List, Dict

import requests
from django.http import HttpResponseServerError
Expand Down Expand Up @@ -43,11 +43,29 @@ def collections_available(cdbs: List[int]):
return HttpResponseServerError('Error requesting solr concept search collection list')


def _process_result_repsonse(resp: Dict):
uniq_results_map = {}
docs = [d for d in resp['response']['docs']]
for d in docs:
if d['cui'][0] not in uniq_results_map:
parsed_doc = {
'cui': str(d['cui'][0]),
'pretty_name': d['pretty_name'][0],
'type_ids': d.get('type_ids', []),
'synonyms': d['synonyms']
}
if d.get('icd10'):
parsed_doc['icd10'] = d['icd10'][0]
if d.get('opcs4'):
parsed_doc['opcs4'] = d['opcs4'][0]
uniq_results_map[d['cui'][0]] = parsed_doc
return uniq_results_map


def search_collection(cdbs: List[int], raw_query: str):
query = raw_query.strip().replace(r'\s+', r'\s').split(' ')
if len(query) == 1 and query[0] == '':
return Response({'results': []})

res = []
if len(cdbs) > 0:
uniq_results_map = {}
Expand All @@ -69,24 +87,20 @@ def search_collection(cdbs: List[int], raw_query: str):
solr_url = f'http://{SOLR_HOST}:{SOLR_PORT}/solr/{collection_name}/select?q.op=OR&q={query_str}&rows=15'
logger.info(f'Searching solr collection: {solr_url}')
resp = json.loads(requests.get(solr_url).text)

if 'error' in resp:
return HttpResponseServerError(f'Concept Search Index {collection_name} not available, '
f'import concept DB first before trying to search it.')
elif len(resp['response']['docs']) == 0:
# try with wildcards at the end of the entire query, rather than each token
fallback_query = f'name:{" ".join(query)}* synonyms:{" ".join(query)}*'
solr_url = f'http://{SOLR_HOST}:{SOLR_PORT}/solr/{collection_name}/select?q.op=OR&q={fallback_query}&rows=15'
logger.info(f'Searching solr collection with fall back query at url: {solr_url}')
resp = json.loads(requests.get(solr_url).text)
uniq_results_map.update(_process_result_repsonse(resp))
else:
docs = [d for d in resp['response']['docs']]
for d in docs:
if d['cui'][0] not in uniq_results_map:
parsed_doc = {
'cui': str(d['cui'][0]),
'pretty_name': d['pretty_name'][0],
'type_ids': d.get('type_ids', []),
'synonyms': d['synonyms']
}
if d.get('icd10'):
parsed_doc['icd10'] = d['icd10'][0]
if d.get('opcs4'):
parsed_doc['opcs4'] = d['opcs4'][0]
uniq_results_map[d['cui'][0]] = parsed_doc
uniq_results_map.update(_process_result_repsonse(resp))

res = sorted(uniq_results_map.values(), key=lambda r: len(r['pretty_name']))
return Response({'results': res})

Expand Down
22 changes: 16 additions & 6 deletions webapp/frontend/src/components/anns/AddAnnotation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
<tr @keyup.stop>
<td>Concept Lookup</td>
<td>
<concept-picker :project="project" :selection="name" @pickedResult:concept="enrichCUI">
<concept-picker :project="project" :selection="name" @pickedResult:concept="enrichCUI"
@picker:opened="conceptPickerState(true)" @picker:closed="conceptPickerState(false)">
</concept-picker>
</td>
</tr>
Expand Down Expand Up @@ -110,7 +111,8 @@ export default {
name: this.selection.selStr,
prevText: this.selection.prevText,
nextText: this.selection.nextText,
selectedCUI: null
selectedCUI: null,
conceptPickerOpen: false
}
},
methods: {
Expand Down Expand Up @@ -148,11 +150,19 @@ export default {
cancel () {
this.$emit('request:addAnnotationComplete')
},
keyup (e) {
if (e.keyCode === 27) {
keydown (e) {
if (e.keyCode === 27) { // esc key
this.cancel()
} else if (e.keyCode === 13 && !this.conceptPickerOpen) { // enter key
this.submit()
}
},
conceptPickerState (val) {
const that = this
window.setTimeout(function () {
that.conceptPickerOpen = val
}, 100)
},
newConceptSelected () {
this.selectedCUI = null
},
Expand All @@ -161,10 +171,10 @@ export default {
}
},
mounted () {
window.addEventListener('keyup', this.keyup)
window.addEventListener('keydown', this.keydown)
},
beforeDestroy () {
window.removeEventListener('keyup', this.keyup)
window.removeEventListener('keydown', this.keydown)
}
}
</script>
Expand Down
11 changes: 6 additions & 5 deletions webapp/frontend/src/components/anns/TaskBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export default {
submitLocked: Boolean,
altSearch: Boolean,
terminateEnabled: Boolean,
irrelevantEnabled: Boolean
irrelevantEnabled: Boolean,
conceptSelection: Object
},
watch: {
'submitLocked' (oldVal, newVal) {
Expand Down Expand Up @@ -67,8 +68,8 @@ export default {
}
return true
},
keyup (e) {
if (e.keyCode === 13) {
keydown (e) {
if (e.keyCode === 13 && !this.conceptSelection) {
if (!this.submitDisabled()) {
this.ignoreSubmit()
this.submit()
Expand Down Expand Up @@ -100,10 +101,10 @@ export default {
}
},
listenSubmit () {
window.addEventListener('keyup', this.keyup)
window.addEventListener('keydown', this.keydown)
},
ignoreSubmit () {
window.removeEventListener('keyup', this.keyup)
window.removeEventListener('keydown', this.keydown)
}
},
mounted () {
Expand Down
2 changes: 1 addition & 1 deletion webapp/frontend/src/components/common/ClinicalText.vue
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export default {
const anchor = selection.anchorNode
const focus = selection.focusNode
if (selStr.length > 0 && focus !== null) {
if (selStr.length > 0 && focus !== null && focus.data) {
let nextText = focus.data.slice(selection.focusOffset)
let nextSibling = focus.nextSibling || focus.parentElement.nextSibling
let priorText = anchor.data.slice(0, selection.anchorOffset)
Expand Down
6 changes: 4 additions & 2 deletions webapp/frontend/src/components/common/ConceptPicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
:appendToBody="true"
:options="searchResults"
:loading="loadingResults"
label="cui">
label="cui"
@open="$emit('picker:opened')"
@close="$emit('picker:closed')">
<template v-slot:option="option">
<span class="select-option">{{option.name}}</span>
<span class="select-option-cui"> - {{option.cui}}</span>
Expand Down Expand Up @@ -34,7 +36,7 @@ export default {
el.focus()
el.value = that.selection
that.searchCUI(that.selection)
}, 500)
}, 150)
},
data () {
return {
Expand Down
3 changes: 2 additions & 1 deletion webapp/frontend/src/components/common/ConceptSummary.vue
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ export default {
if (this.project.cdb_search_filter.length > 0) {
this.$http.get(`/api/concept-dbs/${this.project.cdb_search_filter[0]}/`).then(resp => {
if (resp.data) {
that.searchFilterDBIndex = `${resp.data.name}_id_${that.project.cdb_search_filter}`
// this is a bit hacky - backend should just return the correct CDB search filter
that.$set(that, 'searchFilterDBIndex', `${resp.data.name}_id_${that.project.cdb_search_filter}`)
this.fetchDetail(this.selectedEnt, this.searchFilterDBIndex, () => {
that.cleanProps()
})
Expand Down
21 changes: 13 additions & 8 deletions webapp/frontend/src/views/TrainAnnotations.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
<div @click="selectRelation(null)" class="container-fluid app-container">
<div class="app-header">
<div class="project-name">
<span>
<h4>{{ project === null ? '' : project.name }}</h4>
</span>
<h4>{{ project === null ? '' : project.name }}</h4>
</div>

<div class="meta">
Expand Down Expand Up @@ -37,12 +35,14 @@
:current-ent="currentEnt" :ents="ents" :task-name="taskName" :task-values="taskValues"
:addAnnos="true" :current-rel-start-ent="(currentRel || {}).start_entity"
:current-rel-end-ent="(currentRel || {}).end_entity"
@select:concept="selectEntity" @select:addSynonym="addSynonym"></clinical-text>
@select:concept="selectEntity" @select:addSynonym="addSynonym"
@pick:concept="conceptPickerState"></clinical-text>
<div class="taskbar">
<nav-bar class="nav" :ents="ents" :currentEnt="currentEnt" @select:next="next" @select:back="back"></nav-bar>
<task-bar class="tasks" :taskLocked="taskLocked" :ents="ents" :altSearch="altSearch"
:submitLocked="docToSubmit !== null" :terminateEnabled="(project || {}).terminate_available"
:irrelevantEnabled="(project || {}).irrelevant_available"
:conceptSelection="conceptSynonymSelection"
@select:remove="markRemove" @select:correct="markCorrect"
@select:kill="markKill" @select:alternative="toggleAltSearch"
@select:irrelevant="markIrrelevant" @submit="submitDoc"></task-bar>
Expand Down Expand Up @@ -325,6 +325,7 @@ export default {
helpModal: false,
projectCompleteModal: false,
resetModal: false,
conceptPickerOpen: true,
errors: {
modal: false,
message: '',
Expand Down Expand Up @@ -606,12 +607,14 @@ export default {
that.metaAnnotate = false
}, 50)
},
conceptPickerState (val) {
this.conceptPickerOpen = val
},
next () {
this.selectEntity(this.ents.indexOf(this.currentEnt) + 1)
},
back () {
this.selectEntity(this.ents.indexOf(this.currentEnt) - 1)
this.selectEntity(this.ents.indexOf(this.currentEnt) - 1)
},
submitDoc (docId) {
if (this.docToSubmit === null) {
Expand Down Expand Up @@ -703,16 +706,18 @@ export default {
})
}
},
keyup (e) {
keydown (e) {
if (e.keyCode === 13 && this.docToSubmit && !this.submitConfirmedLoading) {
this.submitConfirmed()
} else if (e.keyCode === 27 && this.docToSubmit) {
this.docToSubmit = null
}
},
confirmSubmitListenerRemove () {
window.removeEventListener('keyup', this.keyup)
window.removeEventListener('keydown', this.keydown)
},
confirmSubmitListenerAdd () {
window.addEventListener('keyup', this.keyup)
window.addEventListener('keydown', this.keydown)
},
confirmReset () {
this.loadingDoc = true
Expand Down

0 comments on commit 3d544e6

Please sign in to comment.