From 65a296bcd3010ded925b1b4724e7f9c4aad47f27 Mon Sep 17 00:00:00 2001 From: Viktor Kovtun <viktor.kovtun@id.ethz.ch> Date: Thu, 15 Oct 2020 15:57:35 +0200 Subject: [PATCH] SSDM-10317 Added search by material support to full text search. --- .../search/planner/GlobalSearchManager.java | 6 +++ .../GlobalSearchCriteriaTranslator.java | 43 ++++++++++++++++--- .../systemtest/asapi/v3/GlobalSearchTest.java | 26 ++++++++++- 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/planner/GlobalSearchManager.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/planner/GlobalSearchManager.java index 11110cd7c9d..5d6ed435e47 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/planner/GlobalSearchManager.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/planner/GlobalSearchManager.java @@ -310,6 +310,12 @@ public class GlobalSearchManager implements IGlobalSearchManager addPropertyMatch(cvCodeMatch, fieldsMap, matches); } + final String materialMatch = (String) fieldsMap.get(MATERIAL_MATCH_ALIAS); + if (materialMatch != null) + { + addPropertyMatch(materialMatch, fieldsMap, matches); + } + final String sampleMatch = (String) fieldsMap.get(SAMPLE_MATCH_ALIAS); if (sampleMatch != null) { diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/translator/GlobalSearchCriteriaTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/translator/GlobalSearchCriteriaTranslator.java index ca9c4d046a8..929eb3e8fdd 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/translator/GlobalSearchCriteriaTranslator.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/translator/GlobalSearchCriteriaTranslator.java @@ -48,6 +48,8 @@ public class GlobalSearchCriteriaTranslator public static final String SAMPLE_IDENTIFIER_MATCH_ALIAS = "sample_identifier_match"; + public static final String MATERIAL_MATCH_ALIAS = "material_match"; + public static final String SAMPLE_MATCH_ALIAS = "sample_match"; public static final String ENTITY_TYPES_CODE_ALIAS = "enty_code"; @@ -88,6 +90,8 @@ public class GlobalSearchCriteriaTranslator private static final String SAMPLES_TABLE_ALIAS = "samp"; + private static final String MATERIALS_TABLE_ALIAS = "mat"; + private static final String SPACE_TABLE_ALIAS = "space"; private static final String PROJECT_TABLE_ALIAS = "proj"; @@ -257,6 +261,8 @@ public class GlobalSearchCriteriaTranslator sqlBuilder.append(SP).append(SAMPLE_IDENTIFIER_MATCH_ALIAS).append(COMMA).append(NL); } + sqlBuilder.append(NULL).append(SP).append(MATERIAL_MATCH_ALIAS).append(COMMA).append(NL); + if (tableMapper == SAMPLE || tableMapper == EXPERIMENT || tableMapper == DATA_SET) { sqlBuilder.append(NULL).append(SP).append(SAMPLE_MATCH_ALIAS).append(COMMA).append(NL); @@ -306,6 +312,9 @@ public class GlobalSearchCriteriaTranslator sqlBuilder.append(NULL).append(SP).append(SAMPLE_IDENTIFIER_MATCH_ALIAS).append(COMMA).append(NL); } + buildMaterialMatch(sqlBuilder, criterionValues, args); + sqlBuilder.append(COMMA).append(NL); + if (tableMapper == SAMPLE || tableMapper == EXPERIMENT || tableMapper == DATA_SET) { buildSampleMatch(sqlBuilder, criterionValues, args); @@ -362,20 +371,29 @@ public class GlobalSearchCriteriaTranslator final List<Object> args) { sqlBuilder.append(CASE).append(NL); - appendWhenThen(sqlBuilder, PERM_ID_COLUMN, values, args); - appendWhenThen(sqlBuilder, CODE_COLUMN, values, args); - appendWhenThen(sqlBuilder, SAMPLE_IDENTIFIER_COLUMN, values, args); + appendWhenThen(sqlBuilder, SAMPLES_TABLE_ALIAS, PERM_ID_COLUMN, values, args); + appendWhenThen(sqlBuilder, SAMPLES_TABLE_ALIAS, CODE_COLUMN, values, args); + appendWhenThen(sqlBuilder, SAMPLES_TABLE_ALIAS, SAMPLE_IDENTIFIER_COLUMN, values, args); sqlBuilder.append('\t').append(ELSE).append(SP).append(NULL).append(NL); sqlBuilder.append(END).append(SP).append(SAMPLE_MATCH_ALIAS); } - private static void appendWhenThen(final StringBuilder sqlBuilder, final String column, final String[] values, + private static void buildMaterialMatch(final StringBuilder sqlBuilder, final String[] values, final List<Object> args) + { + sqlBuilder.append(CASE).append(NL); + appendWhenThen(sqlBuilder, MATERIALS_TABLE_ALIAS, CODE_COLUMN, values, args); + sqlBuilder.append('\t').append(ELSE).append(SP).append(NULL).append(NL); + sqlBuilder.append(END).append(SP).append(MATERIAL_MATCH_ALIAS); + } + + private static void appendWhenThen(final StringBuilder sqlBuilder, final String tableAlias, final String column, + final String[] values, final List<Object> args) { sqlBuilder.append('\t').append(WHEN).append(SP).append(LOWER).append(LP) - .append(SAMPLES_TABLE_ALIAS).append(PERIOD).append(column).append(RP).append(SP).append(IN).append(SP) - .append(SELECT_UNNEST) - .append(THEN).append(SP).append(SAMPLES_TABLE_ALIAS).append(PERIOD).append(column).append(NL); + .append(tableAlias).append(PERIOD).append(column).append(RP).append(SP).append(IN).append(SP) + .append(SELECT_UNNEST).append(SP) + .append(THEN).append(SP).append(tableAlias).append(PERIOD).append(column).append(NL); args.add(values); } @@ -604,6 +622,11 @@ public class GlobalSearchCriteriaTranslator .append(VOCABULARY_TERM_COLUMN).append(SP).append(EQ).append(SP).append(CONTROLLED_VOCABULARY_TERMS_TABLE_ALIAS).append(PERIOD) .append(ID_COLUMN).append(NL); + sqlBuilder.append(LEFT_JOIN).append(SP).append(MATERIAL.getEntitiesTable()).append(SP) + .append(MATERIALS_TABLE_ALIAS).append(SP).append(ON).append(SP).append(PROPERTIES_TABLE_ALIAS) + .append(PERIOD).append(MATERIAL_PROP_COLUMN).append(SP).append(EQ).append(SP) + .append(MATERIALS_TABLE_ALIAS).append(PERIOD).append(ID_COLUMN).append(NL); + if (tableMapper == TableMapper.SAMPLE || tableMapper == TableMapper.EXPERIMENT || tableMapper == TableMapper.DATA_SET) { @@ -691,6 +714,12 @@ public class GlobalSearchCriteriaTranslator .append(DOUBLE_AT).append(SP); buildTsQueryPart(sqlBuilder, stringValue, args); + sqlBuilder.append(SP).append(OR).append(SP); + + sqlBuilder.append(MATERIALS_TABLE_ALIAS).append(PERIOD).append(TS_VECTOR_COLUMN).append(SP) + .append(DOUBLE_AT).append(SP).append(QU).append(DOUBLE_COLON).append(TSQUERY); + args.add(toTsQueryText(stringValue)); + if (tableMapper == TableMapper.SAMPLE || tableMapper == TableMapper.EXPERIMENT || tableMapper == TableMapper.DATA_SET) { diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/GlobalSearchTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/GlobalSearchTest.java index 213706a84ad..3c23fb623e3 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/GlobalSearchTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/GlobalSearchTest.java @@ -1153,7 +1153,31 @@ public class GlobalSearchTest extends AbstractTest } } - public List<GlobalSearchObject> filterSearchResults(final List<GlobalSearchObject> results, + @Test + public void testSearchMatchingMaterialProperty() + { + final GlobalSearchCriteria criteria = new GlobalSearchCriteria(); + criteria.withText().thatContains("BACTERIUM-Y"); + + final GlobalSearchObjectFetchOptions fo = new GlobalSearchObjectFetchOptions(); + fo.sortBy().objectPermId().asc(); + fo.withMatch(); + + final SearchResult<GlobalSearchObject> result = search(TEST_USER, criteria, fo); + final List<GlobalSearchObject> objects = result.getObjects(); + + assertEquals(result.getTotalCount(), 4); + assertEquals(objects.size(), 4); + + assertSample(objects.get(0), "200902091250077-1026", "/CISD/CP-TEST-2", "Property 'bacterium': BACTERIUM-Y"); + assertSample(objects.get(1), "200902091250077-1051", "/CISD/PLATE_WELLSEARCH:WELL-A01", + "Property 'bacterium': BACTERIUM-Y"); + assertExperiment(objects.get(2), "201108050937246-1031", "/CISD/DEFAULT/EXP-Y", + "Property 'any_material': BACTERIUM-Y"); + assertMaterial(objects.get(3), "BACTERIUM-Y", "BACTERIUM", "Identifier: BACTERIUM-Y (BACTERIUM)"); + } + + private List<GlobalSearchObject> filterSearchResults(final List<GlobalSearchObject> results, final boolean withDataset, final boolean withSample, final boolean withExperiment) { return results.stream().filter(globalSearchObject -> -- GitLab