SOLR-3956: Fixed group.facet=true to work with negative facet.limit

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1462227 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Chris M. Hostetter 2013-03-28 17:37:23 +00:00
parent 175b33d5c7
commit 1ad382f304
6 changed files with 105 additions and 19 deletions

View File

@ -184,15 +184,15 @@ public abstract class AbstractGroupFacetCollector extends Collector {
*/
public List<FacetEntry> getFacetEntries(int offset, int limit) {
List<FacetEntry> entries = new LinkedList<FacetEntry>();
limit += offset;
int i = 0;
int skipped = 0;
int included = 0;
for (FacetEntry facetEntry : facetEntries) {
if (i < offset) {
i++;
if (skipped < offset) {
skipped++;
continue;
}
if (i++ >= limit) {
if (included++ >= limit) {
break;
}
entries.add(facetEntry);

View File

@ -88,19 +88,40 @@ public class GroupFacetCollectorTest extends AbstractGroupingTestCase {
w.addDocument(doc);
IndexSearcher indexSearcher = new IndexSearcher(w.getReader());
AbstractGroupFacetCollector groupedAirportFacetCollector = createRandomCollector(useDv ? "hotel_dv" : "hotel", useDv ? "airport_dv" : "airport", null, false);
indexSearcher.search(new MatchAllDocsQuery(), groupedAirportFacetCollector);
TermGroupFacetCollector.GroupedFacetResult airportResult = groupedAirportFacetCollector.mergeSegmentResults(10, 0, false);
assertEquals(3, airportResult.getTotalCount());
assertEquals(0, airportResult.getTotalMissingCount());
List<TermGroupFacetCollector.FacetEntry> entries = airportResult.getFacetEntries(0, 10);
assertEquals(2, entries.size());
assertEquals("ams", entries.get(0).getValue().utf8ToString());
assertEquals(2, entries.get(0).getCount());
assertEquals("dus", entries.get(1).getValue().utf8ToString());
assertEquals(1, entries.get(1).getCount());
List<TermGroupFacetCollector.FacetEntry> entries = null;
AbstractGroupFacetCollector groupedAirportFacetCollector = null;
TermGroupFacetCollector.GroupedFacetResult airportResult = null;
for (int limit : new int[] { 2, 10, 100, Integer.MAX_VALUE }) {
// any of these limits is plenty for the data we have
groupedAirportFacetCollector = createRandomCollector
(useDv ? "hotel_dv" : "hotel",
useDv ? "airport_dv" : "airport", null, false);
indexSearcher.search(new MatchAllDocsQuery(), groupedAirportFacetCollector);
int maxOffset = 5;
airportResult = groupedAirportFacetCollector.mergeSegmentResults
(Integer.MAX_VALUE == limit ? limit : maxOffset + limit, 0, false);
assertEquals(3, airportResult.getTotalCount());
assertEquals(0, airportResult.getTotalMissingCount());
entries = airportResult.getFacetEntries(maxOffset, limit);
assertEquals(0, entries.size());
entries = airportResult.getFacetEntries(0, limit);
assertEquals(2, entries.size());
assertEquals("ams", entries.get(0).getValue().utf8ToString());
assertEquals(2, entries.get(0).getCount());
assertEquals("dus", entries.get(1).getValue().utf8ToString());
assertEquals(1, entries.get(1).getCount());
entries = airportResult.getFacetEntries(1, limit);
assertEquals(1, entries.size());
assertEquals("dus", entries.get(0).getValue().utf8ToString());
assertEquals(1, entries.get(0).getCount());
}
AbstractGroupFacetCollector groupedDurationFacetCollector = createRandomCollector(useDv ? "hotel_dv" : "hotel", useDv ? "duration_dv" : "duration", null, false);
indexSearcher.search(new MatchAllDocsQuery(), groupedDurationFacetCollector);

View File

@ -108,6 +108,9 @@ Bug Fixes
* SOLR-4405: Admin UI - admin-extra files are not rendered into the core-menu (steffkes)
* SOLR-3956: Fixed group.facet=true to work with negative facet.limit
(Chris van der Merwe, hossman)
Optimizations
----------------------

View File

@ -460,12 +460,16 @@ public class SimpleFacets {
TermGroupFacetCollector collector = TermGroupFacetCollector.createTermGroupFacetCollector(groupField, field, multiToken, prefixBR, 128);
searcher.search(new MatchAllDocsQuery(), base.getTopFilter(), collector);
boolean orderByCount = sort.equals(FacetParams.FACET_SORT_COUNT) || sort.equals(FacetParams.FACET_SORT_COUNT_LEGACY);
TermGroupFacetCollector.GroupedFacetResult result = collector.mergeSegmentResults(offset + limit, mincount, orderByCount);
TermGroupFacetCollector.GroupedFacetResult result
= collector.mergeSegmentResults(limit < 0 ? Integer.MAX_VALUE :
(offset + limit),
mincount, orderByCount);
CharsRef charsRef = new CharsRef();
FieldType facetFieldType = searcher.getSchema().getFieldType(field);
NamedList<Integer> facetCounts = new NamedList<Integer>();
List<TermGroupFacetCollector.FacetEntry> scopedEntries = result.getFacetEntries(offset, limit);
List<TermGroupFacetCollector.FacetEntry> scopedEntries
= result.getFacetEntries(offset, limit < 0 ? Integer.MAX_VALUE : limit);
for (TermGroupFacetCollector.FacetEntry facetEntry : scopedEntries) {
facetFieldType.indexedToReadable(facetEntry.getValue(), charsRef);
facetCounts.add(charsRef.toString(), facetEntry.getCount());

View File

@ -137,7 +137,11 @@ public class TestDistributedGrouping extends BaseDistributedSearchTestCase {
for (int shard = 0; shard < clients.size(); shard++) {
int groupValue = values[shard];
for (int i = 500; i < 600; i++) {
index_specific(shard, i1, groupValue, s1, "a", id, i * (shard + 1), t1, shard);
index_specific(shard,
i1, groupValue,
s1, "a",
id, i * (shard + 1),
t1, random().nextInt(7));
}
}
@ -197,6 +201,17 @@ public class TestDistributedGrouping extends BaseDistributedSearchTestCase {
query("q", "*:*", "fq", s1 + ":a", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "group.ngroups", "true");
query("q", "*:*", "fq", s1 + ":a", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "group.truncate", "true");
query("q", "*:*", "fq", s1 + ":a", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "group.truncate", "true", "facet", "true", "facet.field", t1);
for (String gfacet : new String[] { "true", "false" }) {
for (String flimit : new String[] { "-100","-1", "1", "2", "10000" }) {
for (String foffset : new String[] { "0","1", "2", "1000" }) {
query("q", "*:*", "fq", s1+":a",
"rows", 100, "fl", "id,"+i1, "sort", i1+" asc, id asc",
"group", "true", "group.field", i1, "group.limit", 10,
"facet", "true", "facet.field", t1, "group.facet", gfacet,
"facet.limit", flimit, "facet.offset", foffset);
}
}
}
// SOLR-3316
query("q", "*:*", "fq", s1 + ":a", "rows", 0, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "facet", "true", "facet.field", t1);

View File

@ -150,6 +150,15 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
@Test
public void testSimpleGroupedQueryRangeFacets() throws Exception {
// for the purposes of our test data, it shouldn't matter
// if we use facet.limit -100, -1, or 100 ...
// our set of values is small enough either way
testSimpleGroupedQueryRangeFacets("-100");
testSimpleGroupedQueryRangeFacets("-1");
testSimpleGroupedQueryRangeFacets("100");
}
private void testSimpleGroupedQueryRangeFacets(String facetLimit) {
assertQ(
req(
"q", "*:*",
@ -158,6 +167,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
"group.facet", "true",
"group.field", "hotel_s1",
"facet", "true",
"facet.limit", facetLimit,
"facet.query", "airport_s1:ams"
),
"//lst[@name='facet_queries']/int[@name='airport_s1:ams'][.='2']"
@ -172,6 +182,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
"group.facet", "true",
"group.field", "hotel_s1",
"facet", "true",
"facet.limit", facetLimit,
"facet.query", "{!ex=dus}airport_s1:ams"
),
"//lst[@name='facet_queries']/int[@name='{!ex=dus}airport_s1:ams'][.='2']"
@ -184,6 +195,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
"group.facet", "true",
"group.field", "hotel_s1",
"facet", "true",
"facet.limit", facetLimit,
"facet.range", "duration_i1",
"facet.range.start", "5",
"facet.range.end", "11",
@ -206,6 +218,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
"group.facet", "true",
"group.field", "hotel_s1",
"facet", "true",
"facet.limit", facetLimit,
"facet.range", "{!ex=dus}duration_i1",
"facet.range.start", "5",
"facet.range.end", "11",
@ -222,6 +235,16 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
@Test
public void testSimpleGroupedFacets() throws Exception {
// for the purposes of our test data, it shouldn't matter
// if we use facet.limit -100, -1, or 100 ...
// our set of values is small enough either way
testSimpleGroupedFacets("100");
testSimpleGroupedFacets("-100");
testSimpleGroupedFacets("-5");
testSimpleGroupedFacets("-1");
}
private void testSimpleGroupedFacets(String facetLimit) throws Exception {
assertQ(
"Return 5 docs with id range 1937 till 1940",
req("id:[2000 TO 2004]"),
@ -236,6 +259,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
"group.facet", "true",
"group.field", "hotel_s1",
"facet", "true",
"facet.limit", facetLimit,
"facet.field", "airport_s1"
),
"//lst[@name='facet_fields']/lst[@name='airport_s1']",
@ -243,6 +267,23 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
"//lst[@name='airport_s1']/int[@name='ams'][.='2']",
"//lst[@name='airport_s1']/int[@name='dus'][.='1']"
);
assertQ(
"Return one facet count for field airport_a using facet.offset",
req(
"q", "*:*",
"fq", "id:[2000 TO 2004]",
"group", "true",
"group.facet", "true",
"group.field", "hotel_s1",
"facet", "true",
"facet.offset", "1",
"facet.limit", facetLimit,
"facet.field", "airport_s1"
),
"//lst[@name='facet_fields']/lst[@name='airport_s1']",
"*[count(//lst[@name='airport_s1']/int)=1]",
"//lst[@name='airport_s1']/int[@name='dus'][.='1']"
);
assertQ(
"Return two facet counts for field airport_a with fq",
req(
@ -253,6 +294,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
"group.facet", "true",
"group.field", "hotel_s1",
"facet", "true",
"facet.limit", facetLimit,
"facet.field", "airport_s1"
),
"//lst[@name='facet_fields']/lst[@name='airport_s1']",
@ -270,6 +312,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
"group.field", "hotel_s1",
"facet", "true",
"facet.field", "airport_s1",
"facet.limit", facetLimit,
"facet.prefix", "a"
),
"//lst[@name='facet_fields']/lst[@name='airport_s1']",