LUCENE-4461: adding same FacetRequest more than once yielded inconsistent results

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1422670 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Shai Erera 2012-12-16 19:06:02 +00:00
parent 679dbf00b9
commit 4c2f3e74e3
3 changed files with 92 additions and 13 deletions

View File

@ -294,7 +294,10 @@ Bug Fixes
* LUCENE-4633: DirectoryTaxonomyWriter.replaceTaxonomy did not refresh its
internal reader, which could cause an existing category to be added twice.
(Shai Erera)
* LUCENE-4461: If you added the same FacetRequest more than once, you would get
inconsistent results. (Gilad Barkai via Shai Erera)
Changes in Runtime Behavior
* LUCENE-4586: Change default ResultMode of FacetRequest to PER_NODE_IN_TREE.

View File

@ -3,6 +3,7 @@ package org.apache.lucene.facet.search;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.logging.Level;
@ -152,19 +153,21 @@ public class StandardFacetsAccumulator extends FacetsAccumulator {
int offset = part * partitionSize;
// for each partition we go over all requests and handle
// each, where
// the request maintains the merged result.
// In this implementation merges happen after each
// partition,
// each, where the request maintains the merged result.
// In this implementation merges happen after each partition,
// but other impl could merge only at the end.
final HashSet<FacetRequest> handledRequests = new HashSet<FacetRequest>();
for (FacetRequest fr : searchParams.getFacetRequests()) {
FacetResultsHandler frHndlr = fr.createFacetResultsHandler(taxonomyReader);
IntermediateFacetResult res4fr = frHndlr.fetchPartitionResult(facetArrays, offset);
IntermediateFacetResult oldRes = fr2tmpRes.get(fr);
if (oldRes != null) {
res4fr = frHndlr.mergeResults(oldRes, res4fr);
}
fr2tmpRes.put(fr, res4fr);
// Handle and merge only facet requests which were not already handled.
if (handledRequests.add(fr)) {
FacetResultsHandler frHndlr = fr.createFacetResultsHandler(taxonomyReader);
IntermediateFacetResult res4fr = frHndlr.fetchPartitionResult(facetArrays, offset);
IntermediateFacetResult oldRes = fr2tmpRes.get(fr);
if (oldRes != null) {
res4fr = frHndlr.mergeResults(oldRes, res4fr);
}
fr2tmpRes.put(fr, res4fr);
}
}
}
} finally {
@ -260,7 +263,7 @@ public class StandardFacetsAccumulator extends FacetsAccumulator {
int[] intArray = facetArrays.getIntArray();
totalFacetCounts.fillTotalCountsForPartition(intArray, partition);
double totalCountsFactor = getTotalCountsFactor();
// fix total counts, but only if the effect of this would be meaningfull.
// fix total counts, but only if the effect of this would be meaningful.
if (totalCountsFactor < 0.99999) {
int delta = nAccumulatedDocs + 1;
for (int i = 0; i < intArray.length; i++) {

View File

@ -0,0 +1,73 @@
package org.apache.lucene.facet;
import java.util.List;
import org.apache.lucene.facet.search.FacetsCollector;
import org.apache.lucene.facet.search.params.CountFacetRequest;
import org.apache.lucene.facet.search.params.FacetSearchParams;
import org.apache.lucene.facet.search.results.FacetResult;
import org.apache.lucene.facet.taxonomy.CategoryPath;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.junit.After;
import org.junit.Before;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class TestSameRequestAccumulation extends FacetTestBase {
@Override
@Before
public void setUp() throws Exception {
super.setUp();
initIndex();
}
// Following LUCENE-4461 - ensure requesting the (exact) same request more
// than once does not alter the results
public void testTwoSameRequests() throws Exception {
final CountFacetRequest facetRequest = new CountFacetRequest(new CategoryPath("root"), 10);
FacetSearchParams fsp = new FacetSearchParams(facetRequest);
FacetsCollector fc = new FacetsCollector(fsp, indexReader, taxoReader);
searcher.search(new MatchAllDocsQuery(), fc);
final String expected = fc.getFacetResults().get(0).toString();
// now add the same facet request with duplicates (same instance and same one)
fsp = new FacetSearchParams(facetRequest, facetRequest, new CountFacetRequest(new CategoryPath("root"), 10));
// make sure the search params holds 3 requests now
assertEquals(3, fsp.getFacetRequests().size());
fc = new FacetsCollector(fsp, indexReader, taxoReader);
searcher.search(new MatchAllDocsQuery(), fc);
List<FacetResult> actual = fc.getFacetResults();
// all 3 results should have the same toString()
assertEquals("same FacetRequest but different result?", expected, actual.get(0).toString());
assertEquals("same FacetRequest but different result?", expected, actual.get(1).toString());
assertEquals("same FacetRequest but different result?", expected, actual.get(2).toString());
}
@Override
@After
public void tearDown() throws Exception {
closeAll();
super.tearDown();
}
}