mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
SEARCH-107: Extend search public API for multi-select facets
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@131528 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
package org.alfresco.rest.api.search.impl;
|
package org.alfresco.rest.api.search.impl;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.repo.search.impl.lucene.LuceneQueryLanguageSPI;
|
||||||
import org.alfresco.rest.api.search.model.Default;
|
import org.alfresco.rest.api.search.model.Default;
|
||||||
import org.alfresco.rest.api.search.model.FacetField;
|
import org.alfresco.rest.api.search.model.FacetField;
|
||||||
import org.alfresco.rest.api.search.model.FacetFields;
|
import org.alfresco.rest.api.search.model.FacetFields;
|
||||||
@@ -64,6 +65,8 @@ import static org.alfresco.service.cmr.search.SearchService.*;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps from a json request and a solr SearchParameters object.
|
* Maps from a json request and a solr SearchParameters object.
|
||||||
@@ -278,11 +281,29 @@ public class SearchMapper
|
|||||||
throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID,
|
throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID,
|
||||||
new Object[] { ": filterQueries {} not allowed with cmis language" });
|
new Object[] { ": filterQueries {} not allowed with cmis language" });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FilterQuery fq:filterQueries)
|
for (FilterQuery fq:filterQueries)
|
||||||
{
|
{
|
||||||
ParameterCheck.mandatoryString("filterQueries query", fq.getQuery());
|
ParameterCheck.mandatoryString("filterQueries query", fq.getQuery());
|
||||||
sp.addFilterQuery(fq.getQuery());
|
String query = fq.getQuery().trim();
|
||||||
|
if (fq.getTags() == null || fq.getTags().isEmpty() || query.contains("afts tag"))
|
||||||
|
{
|
||||||
|
//If its already got tags then just let it through
|
||||||
|
sp.addFilterQuery(query);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String tags = "tag="+String.join(",", fq.getTags());
|
||||||
|
Matcher matcher = LuceneQueryLanguageSPI.AFTS_QUERY.matcher(query);
|
||||||
|
if (matcher.find())
|
||||||
|
{
|
||||||
|
query = "{!afts "+tags+" "+matcher.group(1).trim()+"}"+matcher.group(2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
query = "{!afts "+tags+" }"+query;
|
||||||
|
}
|
||||||
|
sp.addFilterQuery(query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,8 +352,11 @@ public class SearchMapper
|
|||||||
{
|
{
|
||||||
ParameterCheck.mandatoryString("facetFields facet field", facet.getField());
|
ParameterCheck.mandatoryString("facetFields facet field", facet.getField());
|
||||||
String field = facet.getField();
|
String field = facet.getField();
|
||||||
//String label = facet.getLabel()!=null?facet.getLabel():field;
|
if (facet.getExcludeFilters() != null && !facet.getExcludeFilters().isEmpty())
|
||||||
//field = "{key='"+label+"'}"+field;
|
{
|
||||||
|
int startIndex = field.startsWith("{!afts")?7:0;
|
||||||
|
field = "{!afts ex="+String.join(",", facet.getExcludeFilters())+"}"+field.substring(startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
FieldFacet ff = new FieldFacet(field);
|
FieldFacet ff = new FieldFacet(field);
|
||||||
|
|
||||||
@@ -366,7 +390,6 @@ public class SearchMapper
|
|||||||
ff.setOffset(facet.getOffset());
|
ff.setOffset(facet.getOffset());
|
||||||
ff.setMinCount(facet.getMincount());
|
ff.setMinCount(facet.getMincount());
|
||||||
ff.setEnumMethodCacheMinDF(facet.getFacetEnumCacheMinDf());
|
ff.setEnumMethodCacheMinDF(facet.getFacetEnumCacheMinDf());
|
||||||
|
|
||||||
sp.addFieldFacet(ff);
|
sp.addFieldFacet(ff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,9 @@ import org.alfresco.service.cmr.search.SearchParameters.FieldFacetSort;
|
|||||||
import org.codehaus.jackson.annotate.JsonCreator;
|
import org.codehaus.jackson.annotate.JsonCreator;
|
||||||
import org.codehaus.jackson.annotate.JsonProperty;
|
import org.codehaus.jackson.annotate.JsonProperty;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POJO class representing the FacetField
|
* POJO class representing the FacetField
|
||||||
*
|
*
|
||||||
@@ -47,6 +50,7 @@ public class FacetField
|
|||||||
private final Integer offset;
|
private final Integer offset;
|
||||||
private final Integer mincount;
|
private final Integer mincount;
|
||||||
private final Integer facetEnumCacheMinDf;
|
private final Integer facetEnumCacheMinDf;
|
||||||
|
private final List<String> excludeFilters;
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
public FacetField(@JsonProperty("field") String field,
|
public FacetField(@JsonProperty("field") String field,
|
||||||
@@ -58,6 +62,7 @@ public class FacetField
|
|||||||
@JsonProperty("limit") Integer limit,
|
@JsonProperty("limit") Integer limit,
|
||||||
@JsonProperty("offset") Integer offset,
|
@JsonProperty("offset") Integer offset,
|
||||||
@JsonProperty("mincount") Integer mincount,
|
@JsonProperty("mincount") Integer mincount,
|
||||||
|
@JsonProperty("excludeFilters") List<String> excludeFilters,
|
||||||
@JsonProperty("facetEnumCacheMinDf") Integer facetEnumCacheMinDf)
|
@JsonProperty("facetEnumCacheMinDf") Integer facetEnumCacheMinDf)
|
||||||
{
|
{
|
||||||
this.field = field;
|
this.field = field;
|
||||||
@@ -69,17 +74,14 @@ public class FacetField
|
|||||||
this.limit = limit; //Can be null
|
this.limit = limit; //Can be null
|
||||||
this.offset = offset == null?0:offset;
|
this.offset = offset == null?0:offset;
|
||||||
this.mincount = mincount == null?1:mincount;
|
this.mincount = mincount == null?1:mincount;
|
||||||
|
this.excludeFilters = excludeFilters == null? Collections.emptyList():excludeFilters;
|
||||||
this.facetEnumCacheMinDf = facetEnumCacheMinDf == null?0:facetEnumCacheMinDf;
|
this.facetEnumCacheMinDf = facetEnumCacheMinDf == null?0:facetEnumCacheMinDf;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
|
|
||||||
"excludeFilters": [
|
public List<String> getExcludeFilters()
|
||||||
"string"
|
{
|
||||||
],
|
return excludeFilters;
|
||||||
|
}
|
||||||
"contains": "string",
|
|
||||||
"containsIgnoreCase": true,
|
|
||||||
**/
|
|
||||||
|
|
||||||
public String getField()
|
public String getField()
|
||||||
{
|
{
|
||||||
|
@@ -58,10 +58,13 @@ import org.alfresco.service.cmr.search.LimitBy;
|
|||||||
import org.alfresco.service.cmr.search.SearchParameters;
|
import org.alfresco.service.cmr.search.SearchParameters;
|
||||||
import org.alfresco.service.cmr.search.SearchParameters.FieldFacet;
|
import org.alfresco.service.cmr.search.SearchParameters.FieldFacet;
|
||||||
import org.alfresco.service.cmr.search.SearchService;
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the SearchMapper class
|
* Tests the SearchMapper class
|
||||||
@@ -304,7 +307,7 @@ public class SearchMapperTests
|
|||||||
//Doesn't error
|
//Doesn't error
|
||||||
searchMapper.fromFilterQuery(searchParameters, null);
|
searchMapper.fromFilterQuery(searchParameters, null);
|
||||||
|
|
||||||
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("hedgehog", null), new FilterQuery("king", Arrays.asList("not", "used"))));
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("hedgehog", null), new FilterQuery("king", null)));
|
||||||
assertEquals(2 ,searchParameters.getFilterQueries().size());
|
assertEquals(2 ,searchParameters.getFilterQueries().size());
|
||||||
assertEquals("hedgehog" ,searchParameters.getFilterQueries().get(0));
|
assertEquals("hedgehog" ,searchParameters.getFilterQueries().get(0));
|
||||||
assertEquals("king" ,searchParameters.getFilterQueries().get(1));
|
assertEquals("king" ,searchParameters.getFilterQueries().get(1));
|
||||||
@@ -321,6 +324,33 @@ public class SearchMapperTests
|
|||||||
//You can't specify FilterQuery when using the CMIS language
|
//You can't specify FilterQuery when using the CMIS language
|
||||||
assertNotNull(iae);
|
assertNotNull(iae);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
searchParameters = new SearchParameters();
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{!afts}description:xyz", Arrays.asList("desc1", "desc2"))));
|
||||||
|
assertEquals("{!afts tag=desc1,desc2 }description:xyz" ,searchParameters.getFilterQueries().get(0));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{!afts}description:xyz", Arrays.asList("desc1"))));
|
||||||
|
assertEquals("{!afts tag=desc1 }description:xyz" ,searchParameters.getFilterQueries().get(1));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("description:xyz", Arrays.asList("desc1"))));
|
||||||
|
assertEquals("{!afts tag=desc1 }description:xyz" ,searchParameters.getFilterQueries().get(2));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{!afts} description:xyz", Arrays.asList("desc1"))));
|
||||||
|
assertEquals("{!afts tag=desc1 } description:xyz" ,searchParameters.getFilterQueries().get(3));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery(" {!afts cake} description:xyz", Arrays.asList("desc1"))));
|
||||||
|
assertEquals("{!afts tag=desc1 cake} description:xyz" ,searchParameters.getFilterQueries().get(4));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{!afts tag=desc1}description:xyz", Arrays.asList("desc1"))));
|
||||||
|
assertEquals("{!afts tag=desc1}description:xyz" ,searchParameters.getFilterQueries().get(5));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("created:2011", Arrays.asList("desc1"))));
|
||||||
|
assertEquals("{!afts tag=desc1 }created:2011" ,searchParameters.getFilterQueries().get(6));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("=cm:name:cabbage", Arrays.asList("desc1"))));
|
||||||
|
assertEquals("{!afts tag=desc1 }=cm:name:cabbage" ,searchParameters.getFilterQueries().get(7));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{http://www.alfresco.org/model/content/1.0}title:workflow", null)));
|
||||||
|
assertEquals("{http://www.alfresco.org/model/content/1.0}title:workflow" ,searchParameters.getFilterQueries().get(8));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{http://www.alfresco.org/model/content/1.0}title:workflow", Arrays.asList("desc1"))));
|
||||||
|
assertEquals("{!afts tag=desc1 }{http://www.alfresco.org/model/content/1.0}title:workflow" ,searchParameters.getFilterQueries().get(9));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{!afts} description:xyz", Arrays.asList("desc1", "desc2"))));
|
||||||
|
assertEquals("{!afts tag=desc1,desc2 }description:xyz" ,searchParameters.getFilterQueries().get(0));
|
||||||
|
searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{ !afts } description:xyz", Arrays.asList("desc1", "desc2"))));
|
||||||
|
assertEquals("{!afts tag=desc1,desc2 }description:xyz" ,searchParameters.getFilterQueries().get(0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -427,14 +457,14 @@ public class SearchMapperTests
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField(null,null,null,null,null,null,null,null,null,null))));
|
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField(null,null,null,null,null,null,null,null,null,null,null))));
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalArgumentException iae)
|
} catch (IllegalArgumentException iae)
|
||||||
{
|
{
|
||||||
assertTrue(iae.getLocalizedMessage().contains("facetFields facet field is a mandatory parameter"));
|
assertTrue(iae.getLocalizedMessage().contains("facetFields facet field is a mandatory parameter"));
|
||||||
}
|
}
|
||||||
|
|
||||||
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,null,null,null,null,null,null,null))));
|
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,null,null,null,null,null,null,null,null))));
|
||||||
assertEquals(1 ,searchParameters.getFieldFacets().size());
|
assertEquals(1 ,searchParameters.getFieldFacets().size());
|
||||||
FieldFacet ff = searchParameters.getFieldFacets().get(0);
|
FieldFacet ff = searchParameters.getFieldFacets().get(0);
|
||||||
|
|
||||||
@@ -449,7 +479,7 @@ public class SearchMapperTests
|
|||||||
// assertEquals("{key='myfield'}myfield" ,ff.getField());
|
// assertEquals("{key='myfield'}myfield" ,ff.getField());
|
||||||
|
|
||||||
searchParameters = new SearchParameters();
|
searchParameters = new SearchParameters();
|
||||||
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield","mylabel","myprefix",null,null,null,null,null,null,null))));
|
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield","mylabel","myprefix",null,null,null,null,null,null,null,null))));
|
||||||
|
|
||||||
ff = searchParameters.getFieldFacets().get(0);
|
ff = searchParameters.getFieldFacets().get(0);
|
||||||
// assertEquals("{key='mylabel'}myfield" ,ff.getField());
|
// assertEquals("{key='mylabel'}myfield" ,ff.getField());
|
||||||
@@ -457,7 +487,7 @@ public class SearchMapperTests
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,"badsort",null,null,null,null,null,null))));
|
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,"badsort",null,null,null,null,null,null,null))));
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (InvalidArgumentException iae)
|
catch (InvalidArgumentException iae)
|
||||||
@@ -468,7 +498,7 @@ public class SearchMapperTests
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null, null,"badmethod",null,null,null,null,null))));
|
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null, null,"badmethod",null,null,null,null,null,null))));
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (InvalidArgumentException iae)
|
catch (InvalidArgumentException iae)
|
||||||
@@ -478,12 +508,25 @@ public class SearchMapperTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
searchParameters = new SearchParameters();
|
searchParameters = new SearchParameters();
|
||||||
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,"INDEX","ENUM",null,null,null,null,null))));
|
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,"INDEX","ENUM",null,null,null,null,null,null))));
|
||||||
ff = searchParameters.getFieldFacets().get(0);
|
ff = searchParameters.getFieldFacets().get(0);
|
||||||
assertEquals("INDEX" ,ff.getSort().toString());
|
assertEquals("INDEX" ,ff.getSort().toString());
|
||||||
assertEquals("ENUM" ,ff.getMethod().toString());
|
assertEquals("ENUM" ,ff.getMethod().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromMultiSelectFacetFields() throws Exception
|
||||||
|
{
|
||||||
|
SearchParameters searchParameters = new SearchParameters();
|
||||||
|
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,"INDEX","ENUM",null,null,null,null,Arrays.asList("tag1"),null))));
|
||||||
|
FieldFacet ff = searchParameters.getFieldFacets().get(0);
|
||||||
|
assertEquals("{!afts ex=tag1}myfield" , ff.getField());
|
||||||
|
searchParameters = new SearchParameters();
|
||||||
|
searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("{!afts}thefield",null,null,null,null,null,null,null,null,Arrays.asList("tag5"),null))));
|
||||||
|
ff = searchParameters.getFieldFacets().get(0);
|
||||||
|
assertEquals("{!afts ex=tag5}thefield" , ff.getField());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void fromLimits() throws Exception
|
public void fromLimits() throws Exception
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user