Merged searchbcr (5.2.1) to 5.2.N (5.2.1)

135772 gjames: SEARCH-419: Correct handling of fieldfacet label and exclusion filters


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@136093 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gethin James
2017-03-24 13:15:16 +00:00
parent e2395b1f57
commit 30ec01a0d6
2 changed files with 139 additions and 41 deletions

View File

@@ -474,7 +474,7 @@ public class SolrQueryHTTPClient implements BeanFactoryAware, InitializingBean
}
}
buildUrlParameters(searchParameters, mapping, encoder, url);
buildUrlParameters(searchParameters, mapping.isSharded(), encoder, url);
final String searchTerm = searchParameters.getSearchTerm();
String spellCheckQueryStr = null;
@@ -590,12 +590,12 @@ public class SolrQueryHTTPClient implements BeanFactoryAware, InitializingBean
/**
* Builds most of the Url parameters for a Solr Http request.
* @param searchParameters
* @param mapping
* @param isSharded
* @param encoder
* @param url
* @throws UnsupportedEncodingException
*/
public void buildUrlParameters(SearchParameters searchParameters, SolrStoreMappingWrapper mapping, URLCodec encoder, StringBuilder url)
public void buildUrlParameters(SearchParameters searchParameters, boolean isSharded, URLCodec encoder, StringBuilder url)
throws UnsupportedEncodingException
{
Locale locale = extractLocale(searchParameters);
@@ -633,12 +633,12 @@ public class SolrQueryHTTPClient implements BeanFactoryAware, InitializingBean
url.append("&fq=").append(encoder.encode(filterQuery, "UTF-8"));
}
buildFacetParameters(searchParameters, mapping, encoder, url);
buildFacetParameters(searchParameters, isSharded, encoder, url);
buildFacetIntervalParameters(searchParameters, encoder, url);
buildHightlightParameters(searchParameters, encoder, url);
}
protected void buildFacetParameters(SearchParameters searchParameters, SolrStoreMappingWrapper mapping, URLCodec encoder, StringBuilder url)
protected void buildFacetParameters(SearchParameters searchParameters, boolean isSharded, URLCodec encoder, StringBuilder url)
throws UnsupportedEncodingException
{
if(searchParameters.getFieldFacets().size() > 0 || searchParameters.getFacetQueries().size() > 0)
@@ -646,15 +646,45 @@ public class SolrQueryHTTPClient implements BeanFactoryAware, InitializingBean
url.append("&facet=").append(encoder.encode("true", "UTF-8"));
for(FieldFacet facet : searchParameters.getFieldFacets())
{
url.append("&facet.field=").append(encoder.encode(facet.getField(), "UTF-8"));
url.append("&facet.field=");
String field = facet.getField();
StringBuilder prefix = new StringBuilder("{!afts ");
int startIndex = field.startsWith("{!afts")?7:0;
if (facet.getExcludeFilters() != null && !facet.getExcludeFilters().isEmpty())
{
prefix.append("ex="+String.join(",", facet.getExcludeFilters())+" ");
}
if (facet.getLabel() != null && !facet.getLabel().isEmpty())
{
prefix.append("key="+facet.getLabel()+" ");
}
if (startIndex!=0)
{
int endIndex = field.indexOf("}");
prefix.append(field.substring(startIndex,endIndex>startIndex?endIndex:startIndex));
field = field.substring(endIndex+1);
}
if (prefix.length() > 7)
{
url.append(encoder.encode(prefix.toString().trim(), "UTF-8"));
url.append(encoder.encode("}", "UTF-8"));
}
url.append(encoder.encode(field, "UTF-8"));
if(facet.getEnumMethodCacheMinDF() != 0)
{
url.append("&").append(encoder.encode("f."+facet.getField()+".facet.enum.cache.minDf", "UTF-8")).append("=").append(encoder.encode(""+facet.getEnumMethodCacheMinDF(), "UTF-8"));
url.append("&").append(encoder.encode("f."+field+".facet.enum.cache.minDf", "UTF-8")).append("=").append(encoder.encode(""+facet.getEnumMethodCacheMinDF(), "UTF-8"));
}
int facetLimit;
if(facet.getLimitOrNull() == null)
{
if(mapping.isSharded())
if(isSharded())
{
facetLimit = defaultShardedFacetLimit;
}
@@ -667,30 +697,30 @@ public class SolrQueryHTTPClient implements BeanFactoryAware, InitializingBean
{
facetLimit = facet.getLimitOrNull().intValue();
}
url.append("&").append(encoder.encode("f."+facet.getField()+".facet.limit", "UTF-8")).append("=").append(encoder.encode(""+facetLimit, "UTF-8"));
url.append("&").append(encoder.encode("f."+field+".facet.limit", "UTF-8")).append("=").append(encoder.encode(""+facetLimit, "UTF-8"));
if(facet.getMethod() != null)
{
url.append("&").append(encoder.encode("f."+facet.getField()+".facet.method", "UTF-8")).append("=").append(encoder.encode(facet.getMethod()== FieldFacetMethod.ENUM ? "enum" : "fc", "UTF-8"));
url.append("&").append(encoder.encode("f."+field+".facet.method", "UTF-8")).append("=").append(encoder.encode(facet.getMethod()== FieldFacetMethod.ENUM ? "enum" : "fc", "UTF-8"));
}
if(facet.getMinCount() != 0)
{
url.append("&").append(encoder.encode("f."+facet.getField()+".facet.mincount", "UTF-8")).append("=").append(encoder.encode(""+facet.getMinCount(), "UTF-8"));
url.append("&").append(encoder.encode("f."+field+".facet.mincount", "UTF-8")).append("=").append(encoder.encode(""+facet.getMinCount(), "UTF-8"));
}
if(facet.getOffset() != 0)
{
url.append("&").append(encoder.encode("f."+facet.getField()+".facet.offset", "UTF-8")).append("=").append(encoder.encode(""+facet.getOffset(), "UTF-8"));
url.append("&").append(encoder.encode("f."+field+".facet.offset", "UTF-8")).append("=").append(encoder.encode(""+facet.getOffset(), "UTF-8"));
}
if(facet.getPrefix() != null)
{
url.append("&").append(encoder.encode("f."+facet.getField()+".facet.prefix", "UTF-8")).append("=").append(encoder.encode(""+facet.getPrefix(), "UTF-8"));
url.append("&").append(encoder.encode("f."+field+".facet.prefix", "UTF-8")).append("=").append(encoder.encode(""+facet.getPrefix(), "UTF-8"));
}
if(facet.getSort() != null)
{
url.append("&").append(encoder.encode("f."+facet.getField()+".facet.sort", "UTF-8")).append("=").append(encoder.encode(facet.getSort() == FieldFacetSort.COUNT ? "count" : "index", "UTF-8"));
url.append("&").append(encoder.encode("f."+field+".facet.sort", "UTF-8")).append("=").append(encoder.encode(facet.getSort() == FieldFacetSort.COUNT ? "count" : "index", "UTF-8"));
}
if(facet.isCountDocsMissingFacetField() != false)
{
url.append("&").append(encoder.encode("f."+facet.getField()+".facet.missing", "UTF-8")).append("=").append(encoder.encode(""+facet.isCountDocsMissingFacetField(), "UTF-8"));
url.append("&").append(encoder.encode("f."+field+".facet.missing", "UTF-8")).append("=").append(encoder.encode(""+facet.isCountDocsMissingFacetField(), "UTF-8"));
}
}

View File

@@ -25,6 +25,7 @@
*/
package org.alfresco.repo.search.impl.solr;
import static junit.framework.TestCase.assertEquals;
import static org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_PREFIX;
import static org.junit.Assert.*;
import static org.mockito.Matchers.anyString;
@@ -58,6 +59,7 @@ import org.alfresco.service.cmr.search.Interval;
import org.alfresco.service.cmr.search.IntervalParameters;
import org.alfresco.service.cmr.search.IntervalSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchParameters.FieldFacet;
import org.alfresco.service.cmr.search.SearchParameters.SortDefinition;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.search.StatsParameters;
@@ -102,7 +104,7 @@ public class SolrQueryHTTPClientTest
when(dictionaryService.getProperty(notNull(QName.class))).thenAnswer(invocation ->
{
Object[] args = invocation.getArguments();
QName qName = (QName)args[0];
QName qName = (QName) args[0];
if (qName.getLocalName().contains("created"))
{
return MockClassAttributeDefinition.mockPropertyDefinition(qName, DataTypeDefinition.DATE);
@@ -147,15 +149,16 @@ public class SolrQueryHTTPClientTest
JSONObject body = client.buildStatsBody(params, "myTenant", Locale.US);
assertNotNull(body);
JSONArray tenant = body.getJSONArray("tenants");
assertEquals("myTenant",tenant.get(0).toString());
assertEquals("myTenant", tenant.get(0).toString());
JSONArray locale = body.getJSONArray("locales");
assertEquals("en_US",locale.get(0).toString());
assertEquals("en_US", locale.get(0).toString());
String query = body.getString("query");
assertTrue(query.contains("TYPE:"));
assertTrue(query.contains("{http://www.alfresco.org/model/content/1.0}content"));
}
private StatsParameters getParameters() {
private StatsParameters getParameters()
{
StringBuilder luceneQuery = new StringBuilder();
luceneQuery.append(" +TYPE:\"" + ContentModel.TYPE_CONTENT + "\"");
@@ -163,9 +166,9 @@ public class SolrQueryHTTPClientTest
StatsParameters params = new StatsParameters(SearchService.LANGUAGE_SOLR_FTS_ALFRESCO, luceneQuery.toString(), filterQuery, false);
params.addSort(new SortDefinition(SortDefinition.SortType.FIELD, "contentsize", false));
params.addStatsParameter(StatsParameters.PARAM_FIELD, "contentsize");
params.addStatsParameter(StatsParameters.PARAM_FACET, StatsParameters.FACET_PREFIX+ContentModel.PROP_CREATED.toString());
params.addStatsParameter("Test1", StatsParameters.FACET_PREFIX+"author. .u");
params.addStatsParameter("Test2", StatsParameters.FACET_PREFIX+"creator. .u");
params.addStatsParameter(StatsParameters.PARAM_FACET, StatsParameters.FACET_PREFIX + ContentModel.PROP_CREATED.toString());
params.addStatsParameter("Test1", StatsParameters.FACET_PREFIX + "author. .u");
params.addStatsParameter("Test2", StatsParameters.FACET_PREFIX + "creator. .u");
return params;
}
@@ -175,7 +178,7 @@ public class SolrQueryHTTPClientTest
SearchParameters params = new SearchParameters();
params.setSearchTerm("bob");
StringBuilder urlBuilder = new StringBuilder();
client.buildUrlParameters(params, null, encoder, urlBuilder);
client.buildUrlParameters(params, false, encoder, urlBuilder);
String url = urlBuilder.toString();
assertNotNull(url);
assertFalse(url.contains("&hl"));
@@ -183,7 +186,7 @@ public class SolrQueryHTTPClientTest
urlBuilder = new StringBuilder();
GeneralHighlightParameters highlightParameters = new GeneralHighlightParameters(null, null, null, null, null, null, null, null);
params.setHighlight(highlightParameters);
client.buildUrlParameters(params, null, encoder, urlBuilder);
client.buildUrlParameters(params, true, encoder, urlBuilder);
url = urlBuilder.toString();
assertTrue(url.contains("&hl=true"));
assertTrue(url.contains("&hl.q=bob"));
@@ -191,7 +194,7 @@ public class SolrQueryHTTPClientTest
urlBuilder = new StringBuilder();
highlightParameters = new GeneralHighlightParameters(5, 10, false, "{", "}", 20, true, null);
params.setHighlight(highlightParameters);
client.buildUrlParameters(params, null, encoder, urlBuilder);
client.buildUrlParameters(params, false, encoder, urlBuilder);
url = urlBuilder.toString();
assertTrue(url.contains("&hl=true"));
assertTrue(url.contains("&hl.q=bob"));
@@ -201,42 +204,43 @@ public class SolrQueryHTTPClientTest
assertTrue(url.contains("&hl.mergeContiguous=false"));
assertTrue(url.contains("&hl.usePhraseHighlighter=true"));
assertTrue(url.contains("&hl.simple.pre="+encoder.encode("{", "UTF-8")));
assertTrue(url.contains("&hl.simple.post="+encoder.encode("}", "UTF-8")));
assertTrue(url.contains("&hl.simple.pre=" + encoder.encode("{", "UTF-8")));
assertTrue(url.contains("&hl.simple.post=" + encoder.encode("}", "UTF-8")));
List<FieldHighlightParameters> fields = Arrays.asList(new FieldHighlightParameters(null,null,null,null,null,null));
List<FieldHighlightParameters> fields = Arrays.asList(new FieldHighlightParameters(null, null, null, null, null, null));
urlBuilder = new StringBuilder();
highlightParameters = new GeneralHighlightParameters(5, 10, false, "{", "}", 20, true, fields);
params.setHighlight(highlightParameters);
try
{
client.buildUrlParameters(params, null, encoder, urlBuilder);
client.buildUrlParameters(params, false, encoder, urlBuilder);
fail();
}
catch (IllegalArgumentException iae)
{
assertNotNull("no fieldname specfied so invalid",iae);
assertNotNull("no fieldname specfied so invalid", iae);
}
fields = Arrays.asList(new FieldHighlightParameters("desc",50,100,false,"@","#"), new FieldHighlightParameters("title",55,105,true,"*","¿"));
fields = Arrays.asList(new FieldHighlightParameters("desc", 50, 100, false, "@", "#"),
new FieldHighlightParameters("title", 55, 105, true, "*", "¿"));
urlBuilder = new StringBuilder();
highlightParameters = new GeneralHighlightParameters(5, 10, false, "{", "}", 20, true, fields);
params.setHighlight(highlightParameters);
client.buildUrlParameters(params, null, encoder, urlBuilder);
client.buildUrlParameters(params, false, encoder, urlBuilder);
url = urlBuilder.toString();
assertTrue(url.contains("&hl=true"));
assertTrue(url.contains("&hl.fl="+encoder.encode("desc,title", "UTF-8")));
assertTrue(url.contains("&hl.fl=" + encoder.encode("desc,title", "UTF-8")));
assertTrue(url.contains("&f.desc.hl.snippets=50"));
assertTrue(url.contains("&f.title.hl.snippets=55"));
assertTrue(url.contains("&f.desc.hl.fragsize=100"));
assertTrue(url.contains("&f.title.hl.fragsize=105"));
assertTrue(url.contains("&f.desc.hl.mergeContiguous=false"));
assertTrue(url.contains("&f.title.hl.mergeContiguous=true"));
assertTrue(url.contains("&f.desc.hl.simple.pre="+encoder.encode("@", "UTF-8")));
assertTrue(url.contains("&f.desc.hl.simple.post="+encoder.encode("#", "UTF-8")));
assertTrue(url.contains("&f.title.hl.simple.pre="+encoder.encode("*", "UTF-8")));
assertTrue(url.contains("&f.title.hl.simple.post="+encoder.encode("¿", "UTF-8")));
assertTrue(url.contains("&f.desc.hl.simple.pre=" + encoder.encode("@", "UTF-8")));
assertTrue(url.contains("&f.desc.hl.simple.post=" + encoder.encode("#", "UTF-8")));
assertTrue(url.contains("&f.title.hl.simple.pre=" + encoder.encode("*", "UTF-8")));
assertTrue(url.contains("&f.title.hl.simple.post=" + encoder.encode("¿", "UTF-8")));
}
@@ -267,7 +271,8 @@ public class SolrQueryHTTPClientTest
assertTrue(url.contains("&facet=true"));
assertTrue(url.contains(encoder.encode("{!afts key=numbers}(1,10]", "UTF-8")));
List<Interval> intervalList = Arrays.asList(new Interval("cm:price", "Price", null), new Interval("cm:created", "Created", Arrays.asList(new IntervalSet("2015", "2016-12", "special", false, true))));
List<Interval> intervalList = Arrays.asList(new Interval("cm:price", "Price", null),
new Interval("cm:created", "Created", Arrays.asList(new IntervalSet("2015", "2016-12", "special", false, true))));
params.setInterval(new IntervalParameters(Arrays.asList(intervalSet), intervalList));
urlBuilder = new StringBuilder();
client.buildFacetIntervalParameters(params, encoder, urlBuilder);
@@ -286,4 +291,67 @@ public class SolrQueryHTTPClientTest
TimeZone.setDefault(defaultTimeZone);
}
@Test
public void testBuildFieldFacets() throws UnsupportedEncodingException
{
SearchParameters params = new SearchParameters();
params.setSearchTerm("bob");
SearchParameters.FieldFacet prefixff = new SearchParameters.FieldFacet("{!afts something=right}modifier");
SearchParameters.FieldFacet ff = new SearchParameters.FieldFacet("creator");
params.addFieldFacet(prefixff);
params.addFieldFacet(ff);
StringBuilder urlBuilder = new StringBuilder();
client.buildFacetParameters(params, false, encoder, urlBuilder);
String url = urlBuilder.toString();
assertNotNull(url);
assertTrue(url.contains("&facet=true"));
assertTrue(url.contains("facet.field=creator"));
assertTrue(url.contains("f.creator.facet.limit=100"));
assertTrue(url.contains("facet.field="+encoder.encode("{!afts something=right}modifier", "UTF-8")));
assertTrue(url.contains("f.modifier.facet.limit=100"));
prefixff.setLabel("myLabel");
ff.setLabel("yourLabel");
urlBuilder = new StringBuilder();
client.buildFacetParameters(params, false, encoder, urlBuilder);
url = urlBuilder.toString();
assertNotNull(url);
assertTrue(url.contains("&facet=true"));
assertTrue(url.contains("facet.field="+encoder.encode("{!afts key=yourLabel}creator", "UTF-8")));
assertTrue(url.contains("f.creator.facet.limit=100"));
assertTrue(url.contains("facet.field="+encoder.encode("{!afts key=myLabel something=right}modifier", "UTF-8")));
assertTrue(url.contains("f.modifier.facet.limit=100"));
prefixff.setExcludeFilters(Arrays.asList("x", "y"));
ff.setExcludeFilters(Arrays.asList("B"));
urlBuilder = new StringBuilder();
client.buildFacetParameters(params, false, encoder, urlBuilder);
url = urlBuilder.toString();
assertNotNull(url);
assertTrue(url.contains("&facet=true"));
assertTrue(url.contains("facet.field="+encoder.encode("{!afts ex=B key=yourLabel}creator", "UTF-8")));
assertTrue(url.contains("f.creator.facet.limit=100"));
assertTrue(url.contains("facet.field="+encoder.encode("{!afts ex=x,y key=myLabel something=right}modifier", "UTF-8")));
assertTrue(url.contains("f.modifier.facet.limit=100"));
prefixff.setField("bill");
prefixff.setExcludeFilters(Collections.emptyList());
ff.setField("{!afts}ben");
ff.setLabel(null);
urlBuilder = new StringBuilder();
client.buildFacetParameters(params, false, encoder, urlBuilder);
url = urlBuilder.toString();
assertNotNull(url);
assertTrue(url.contains("&facet=true"));
assertTrue(url.contains("facet.field="+encoder.encode("{!afts ex=B}ben", "UTF-8")));
assertTrue(url.contains("f.ben.facet.limit=100"));
assertTrue(url.contains("facet.field="+encoder.encode("{!afts key=myLabel}bill", "UTF-8")));
assertTrue(url.contains("f.bill.facet.limit=100"));
}
}