Uploaded image for project: 'OpenMRS Core'
  1. OpenMRS Core
  2. TRUNK-2705

Improve concept searching when a concept contains multiple matched concept names




      Fix concept indexing so that if a concept has multiple concept names that include a common word that matches a search phrase then the concept name including the word with highest weight always gets selected to make the concept hit compete favorably with other concepts when sorting hits. Right now the one with the minimum conceptNameId wins which might not necessarily have the highest weight.

      To reproduce this:

      • Find a random concept to edit
      • Add UNIQUE NAME as a synonym and save
      • Edit the concept again and add UNIQUE as another synonym
      • Go to the find concept page and enter UNIQUE

      The name that gets displayed in the results will be UNIQUE NAME instead of UNIQUE and the reason for this is because UNIQUE NAME was added first so it has a lower concept name id, if you added the names in the opposite order, UNIQUE would get displayed.

      A possible solution is to make sure that during concept word creation, only one word with the highest weight ge
      ts stored in case multiple names contain the same word OR a concept word should hold a collection of names for a single concept in which it is contained, this will make it possible to pick the best concept name when executing the query. Use the test below to confirm that the fix works.

      public void getConcepts_shouldReturnASearchResultWhoseConceptNameContainsAWordWithMoreWeight() throws Exception {
      	Concept conceptWithMultipleMatchingNames = conceptService.getConcept(3000);
      	//recalculate the weights just in case the logic for calculating the weights is changed
      	List<ConceptSearchResult> searchResults = conceptService.getConcepts("trust", Collections
      		    .singletonList(Locale.ENGLISH), false, null, null, null, null, null, null, null);
      	Assert.assertEquals(2, searchResults.size());
      	//the first concept is the one with a word with the highest weight
      	Assert.assertEquals(conceptWithMultipleMatchingNames, searchResults.get(0).getConcept());
      	//This test would only pass in case the name selected in the query happens to have a lower concept name id than the others.
      	//For conceptId=3000, its search result should ALWAYS match on 'TRUST ME' because it is shorter THAN 'TRUST ALWAYS'
      	//so it has a higher weight hence giving this concept a higher weight when being compared to other concept hits.
      	Assert.assertEquals(9998, searchResults.get(0).getConceptName().getConceptNameId().intValue());

      Gliffy Diagrams


          Issue Links



                grace Grace Potma
                wyclif Wyclif Luyima
                9 Vote for this issue
                11 Start watching this issue



                  Time Tracking

                    Original Estimate - 4 hours
                    Remaining Estimate - Not Specified
                    Not Specified
                    Time Spent - 3 hours Time Not Required