Skip to content
Snippets Groups Projects
Commit b05901f4 authored by juanf's avatar juanf
Browse files

SP-935 / BIS-517 : ELN UI - Copy YeastLab iPad Search for ELN service

SVN: 30003
parent b62f5aab
No related branches found
No related tags found
No related merge requests found
......@@ -47,10 +47,43 @@ public class SearchResultSorterByScore implements ISearchResultSorter
// 1. Get terms to use as input for the main algorithm
List<Pattern> partialMatchTerms = new ArrayList<Pattern>();
List<String> exactMatchTerms = new ArrayList<String>();
List<Boost> boosts = new ArrayList<Boost>();
for (DetailedSearchCriterion criterion : criteria.getCriteria())
{
partialMatchTerms.add(getPartialMatchTerm(criterion.getValue()));
exactMatchTerms.add(getExactMatchTerm(criterion.getValue()));
switch (criterion.getField().getKind())
{
case ANY_FIELD:
boosts.add(new Boost(1, 1, 1, 1, null));
break;
case ANY_PROPERTY:
boosts.add(new Boost(0, 0, 1, 1, null));
break;
case PROPERTY:
boosts.add(new Boost(0, 0, 0, 1, criterion.getField().getPropertyCode()));
break;
case ATTRIBUTE:
if (criterion.getField().getAttributeCode().equalsIgnoreCase("code"))
{
boosts.add(new Boost(1, 0, 0, 0, null)); // Attribute code
} else if ( // TODO FIX hard coded types, will be clever to not naming the same thing differently internally to avoid this.
criterion.getField().getAttributeCode().equalsIgnoreCase("sample_type")
|| criterion.getField().getAttributeCode().equalsIgnoreCase("data_set_type")
|| criterion.getField().getAttributeCode().equalsIgnoreCase("material_type")
|| criterion.getField().getAttributeCode().equalsIgnoreCase("experiment_type"))
{
boosts.add(new Boost(0, 1, 0, 0, null)); // Attribute type code
} else
{
boosts.add(new Boost(1, 1, 1, 1, null)); // Other attributes not supported, default to general case
}
break;
case REGISTRATOR:
boosts.add(new Boost(1, 1, 1, 1, null)); // Registrator not supported, default to general case
break;
}
}
// 2. Main algorithm
......@@ -58,7 +91,7 @@ public class SearchResultSorterByScore implements ISearchResultSorter
for (IEntitySearchResult entity : entitiesToSort)
{
int score = getScore(entity, partialMatchTerms, exactMatchTerms);
int score = getScore(entity, partialMatchTerms, exactMatchTerms, boosts);
scores.put(entity, score);
}
......@@ -82,41 +115,43 @@ public class SearchResultSorterByScore implements ISearchResultSorter
});
}
private int getScore(IEntitySearchResult entity, List<Pattern> partialMatchTerms, List<String> exactMatchTerms)
private int getScore(IEntitySearchResult entity, List<Pattern> partialMatchTerms, List<String> exactMatchTerms, List<Boost> boosts)
{
int score = 0;
for (int i = 0; i < exactMatchTerms.size(); i++)
{
Pattern partialTerm = partialMatchTerms.get(i);
String exactTerm = exactMatchTerms.get(i);
Boost boost = boosts.get(i);
// 1. Code
if (isPartialMatch(entity.getCode(), partialTerm))
{ // If code matches partially
score += 100000;
score += 100000 * boost.getCodeBoost();
if (isExactMatch(entity.getCode(), exactTerm))
{ // If code matches exactly
score += 1000000;
score += 1000000 * boost.getCodeBoost();
}
}
// 2. Entity type code
if (isExactMatch(entity.getTypeCode(), exactTerm))
{ // If type matches exactly
score += 1000;
score += 1000 * boost.getTypeCodeBoost();
}
// 3. Properties
if (entity.getProperties() != null && entity.getProperties().values() != null)
if (entity.getProperties() != null && entity.getProperties().keySet() != null)
{
for (String propertyValue : entity.getProperties().values())
for (String propertykey : entity.getProperties().keySet())
{
String propertyValue = entity.getProperties().get(propertykey);
if (isPartialMatch(propertyValue, partialTerm))
{ // If property matches partially
score += 100;
score += 100 * boost.getPropertyBoost(propertykey);
if (isExactMatch(propertyValue, exactTerm))
{ // If property matches exactly
score += 10000;
score += 10000 * boost.getPropertyBoost(propertykey);
}
}
}
......@@ -126,6 +161,54 @@ public class SearchResultSorterByScore implements ISearchResultSorter
return score;
}
//
// Helper Methods
//
private static class Boost
{
private int codeBoost;
private int typeCodeBoost;
private int propertyBoost;
private int propertyDefaultBoost;
private String propertyName;
public Boost(int codeBoost, int typeCodeBoost, int propertyDefaultBoost, int propertyBoost, String propertyName)
{
super();
this.codeBoost = codeBoost;
this.typeCodeBoost = typeCodeBoost;
this.propertyDefaultBoost = propertyDefaultBoost;
this.propertyBoost = propertyBoost;
this.propertyName = propertyName;
}
public int getCodeBoost()
{
return codeBoost;
}
public int getTypeCodeBoost()
{
return typeCodeBoost;
}
public int getPropertyBoost(String propertyNameToBoost)
{
if (this.propertyName != null && this.propertyName.equals(propertyNameToBoost))
{
return propertyBoost;
} else
{
return propertyDefaultBoost;
}
}
}
public Pattern getPartialMatchTerm(String term)
{
return Pattern.compile(("*" + term + "*").replace("*", ".*").replace("?", ".?"), Pattern.CASE_INSENSITIVE);
......
......@@ -3,6 +3,10 @@ package ch.systemsx.cisd.openbis.generic.server.business.search.sort;
import static ch.systemsx.cisd.openbis.generic.server.business.search.sort.SearchResultSorterTestHelper.assertEntities;
import static ch.systemsx.cisd.openbis.generic.server.business.search.sort.SearchResultSorterTestHelper.createEntity;
import static ch.systemsx.cisd.openbis.generic.server.business.search.sort.SearchResultSorterTestHelper.getAnyFieldCriterion;
import static ch.systemsx.cisd.openbis.generic.server.business.search.sort.SearchResultSorterTestHelper.getAnyPropertyFieldCriterion;
import static ch.systemsx.cisd.openbis.generic.server.business.search.sort.SearchResultSorterTestHelper.getCodeFieldCriterion;
import static ch.systemsx.cisd.openbis.generic.server.business.search.sort.SearchResultSorterTestHelper.getPropertyFieldCriterion;
import static ch.systemsx.cisd.openbis.generic.server.business.search.sort.SearchResultSorterTestHelper.getTypeCodeFieldCriterion;
import static ch.systemsx.cisd.openbis.generic.server.business.search.sort.SearchResultSorterTestHelper.sort;
import java.util.ArrayList;
......@@ -23,7 +27,7 @@ public class SearchResultSorterByScoreTest extends AssertJUnit
{
@Test
public void testCriteriaAnyCode()
public void testCriteriaAnyForCode()
{
// Entities Setup
List<EntitySearchResult> entities = new ArrayList<EntitySearchResult>();
......@@ -40,7 +44,25 @@ public class SearchResultSorterByScoreTest extends AssertJUnit
}
@Test
public void testCriteriaAnyTypeCode()
public void testCriteriaAtrForCode()
{
// Entities Setup
List<EntitySearchResult> entities = new ArrayList<EntitySearchResult>();
entities.add(createEntity("OTHER_2", "TYPE_2", "CODE"));
entities.add(createEntity("CODE_OTHER", "TYPE"));
entities.add(createEntity("OTHER_1", "TYPE_1", "CODE", "CODE"));
entities.add(createEntity("OTHER_3", "TYPE_3", "CODE", "CODE", "CODE"));
entities.add(createEntity("CODE", "TYPE"));
// Test hit only code
sort(entities, getCodeFieldCriterion("CODE"));
// Verify results
assertEntities(entities, "CODE", "CODE_OTHER", "OTHER_1", "OTHER_2", "OTHER_3");
}
@Test
public void testCriteriaAnyForTypeCode()
{
// Entities Setup
List<EntitySearchResult> entities = new ArrayList<EntitySearchResult>();
......@@ -57,7 +79,25 @@ public class SearchResultSorterByScoreTest extends AssertJUnit
}
@Test
public void testCriteriaAnyProperties()
public void testCriteriaAtrForTypeCode()
{
// Entities Setup
List<EntitySearchResult> entities = new ArrayList<EntitySearchResult>();
entities.add(createEntity("CODE_2", "TYPE_2", "TYPE", "TYPE", "TYPE"));
entities.add(createEntity("CODE_1", "TYPE_1", "TYPE"));
entities.add(createEntity("CODE_3", "OTHER"));
entities.add(createEntity("CODE_4", "TYPE_4", "TYPE", "TYPE"));
entities.add(createEntity("CODE", "TYPE"));
// Test hit only type code
sort(entities, getTypeCodeFieldCriterion("TYPE"));
// Verify results
assertEntities(entities, "CODE", "CODE_1", "CODE_2", "CODE_3", "CODE_4");
}
@Test
public void testCriteriaAnyForProperties()
{
// Entities Setup
List<EntitySearchResult> entities = new ArrayList<EntitySearchResult>();
......@@ -73,6 +113,40 @@ public class SearchResultSorterByScoreTest extends AssertJUnit
assertEntities(entities, "CODE_4", "CODE_3", "CODE_2", "CODE_1");
}
@Test
public void testCriteriaPropForProperties()
{
// Entities Setup
List<EntitySearchResult> entities = new ArrayList<EntitySearchResult>();
entities.add(createEntity("CODE_2", "TYPE_2", "ABC_1", "ABC_2"));
entities.add(createEntity("CODE_1", "TYPE_1", "ABC_1", "ABC"));
entities.add(createEntity("CODE_3", "TYPE_3", "ABC_1", "ABC_2", "ABC_3"));
entities.add(createEntity("CODE_4", "TYPE_4", "ABC"));
// Test hit only properties, partial and exact
sort(entities, getPropertyFieldCriterion("PROP_1", "ABC"));
// Verify results
assertEntities(entities, "CODE_4", "CODE_1", "CODE_2", "CODE_3");
}
@Test
public void testCriteriaAnyPropForProperties()
{
// Entities Setup
List<EntitySearchResult> entities = new ArrayList<EntitySearchResult>();
entities.add(createEntity("CODE_2", "TYPE_2", "ABC_1", "ABC_2"));
entities.add(createEntity("CODE_1", "TYPE_1", "ABC_1", "ABC"));
entities.add(createEntity("CODE_3", "TYPE_3", "ABC_1", "ABC_2", "ABC_3"));
entities.add(createEntity("CODE_4", "TYPE_4", "ABC"));
// Test hit only properties, partial and exact
sort(entities, getAnyPropertyFieldCriterion("ABC"));
// Verify results
assertEntities(entities, "CODE_1", "CODE_4", "CODE_3", "CODE_2");
}
@Test
public void testCriteriaAnyAll()
{
......
......@@ -10,6 +10,7 @@ import junit.framework.Assert;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriterion;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchField;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleAttributeSearchFieldKind;
public class SearchResultSorterTestHelper
{
......@@ -53,6 +54,28 @@ public class SearchResultSorterTestHelper
return new DetailedSearchCriterion(DetailedSearchField.createAnyField(Arrays.asList("ANY")), value);
}
public static DetailedSearchCriterion getPropertyFieldCriterion(String propertyCode, String value)
{
return new DetailedSearchCriterion(DetailedSearchField.createPropertyField(propertyCode), value);
}
public static DetailedSearchCriterion getAnyPropertyFieldCriterion(String value)
{
return new DetailedSearchCriterion(DetailedSearchField.createAnyPropertyField(Arrays.asList("ANY")), value);
}
public static DetailedSearchCriterion getCodeFieldCriterion(String value)
{
// TODO refactor it not to use sample specific class
return new DetailedSearchCriterion(DetailedSearchField.createAttributeField(SampleAttributeSearchFieldKind.CODE), value);
}
public static DetailedSearchCriterion getTypeCodeFieldCriterion(String value)
{
// TODO refactor it not to use sample specific class
return new DetailedSearchCriterion(DetailedSearchField.createAttributeField(SampleAttributeSearchFieldKind.SAMPLE_TYPE), value);
}
public static EntitySearchResult createEntity(String code, String typeCode, String... propertyValues)
{
Map<String, String> properties = new HashMap<String, String>();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment