1 package org.apache.lucene.facet.search;
3 import java.io.IOException;
4 import java.util.Arrays;
7 import org.apache.lucene.index.Term;
8 import org.apache.lucene.search.Query;
9 import org.apache.lucene.search.TermQuery;
10 import org.junit.Before;
11 import org.junit.Test;
13 import org.apache.lucene.facet.FacetTestBase;
14 import org.apache.lucene.facet.search.FacetsAccumulator;
15 import org.apache.lucene.facet.search.ScoredDocIDs;
16 import org.apache.lucene.facet.search.ScoredDocIDsIterator;
17 import org.apache.lucene.facet.search.ScoredDocIdCollector;
18 import org.apache.lucene.facet.search.StandardFacetsAccumulator;
19 import org.apache.lucene.facet.search.params.CountFacetRequest;
20 import org.apache.lucene.facet.search.params.FacetSearchParams;
21 import org.apache.lucene.facet.search.params.ScoreFacetRequest;
22 import org.apache.lucene.facet.search.results.FacetResult;
23 import org.apache.lucene.facet.search.results.FacetResultNode;
24 import org.apache.lucene.facet.taxonomy.CategoryPath;
27 * Licensed to the Apache Software Foundation (ASF) under one or more
28 * contributor license agreements. See the NOTICE file distributed with
29 * this work for additional information regarding copyright ownership.
30 * The ASF licenses this file to You under the Apache License, Version 2.0
31 * (the "License"); you may not use this file except in compliance with
32 * the License. You may obtain a copy of the License at
34 * http://www.apache.org/licenses/LICENSE-2.0
36 * Unless required by applicable law or agreed to in writing, software
37 * distributed under the License is distributed on an "AS IS" BASIS,
38 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39 * See the License for the specific language governing permissions and
40 * limitations under the License.
43 /** Test ScoredDocIdCollector. */
44 public class TestScoredDocIdCollector extends FacetTestBase {
48 public void setUp() throws Exception {
54 public void tearDown() throws Exception {
60 public void testConstantScore() throws Exception {
61 // test that constant score works well
63 Query q = new TermQuery(new Term(CONTENT_FIELD, "white"));
65 System.out.println("Query: " + q);
67 float constScore = 17.0f;
68 ScoredDocIdCollector dCollector = ScoredDocIdCollector.create(indexReader
69 .maxDoc(), false); // scoring is disabled
70 dCollector.setDefaultScore(constScore);
71 searcher.search(q, dCollector);
73 // verify by doc scores at the level of doc-id-iterator
74 ScoredDocIDs scoredDocIDs = dCollector.getScoredDocIDs();
75 assertEquals("Wrong number of matching documents!", 2, scoredDocIDs.size());
76 ScoredDocIDsIterator docItr = scoredDocIDs.iterator();
77 while (docItr.next()) {
78 assertEquals("Wrong score for doc " + docItr.getDocID(), constScore,
79 docItr.getScore(), Double.MIN_VALUE);
82 // verify by facet values
83 List<FacetResult> countRes = findFacets(scoredDocIDs, getFacetedSearchParams());
84 List<FacetResult> scoreRes = findFacets(scoredDocIDs, sumScoreSearchParams());
86 assertEquals("Wrong number of facet count results!", 1, countRes.size());
87 assertEquals("Wrong number of facet score results!", 1, scoreRes.size());
89 FacetResultNode parentCountRes = countRes.get(0).getFacetResultNode();
90 FacetResultNode parentScoreRes = scoreRes.get(0).getFacetResultNode();
92 assertEquals("Wrong number of top count aggregated categories!", 3,
93 parentCountRes.getNumSubResults());
94 assertEquals("Wrong number of top score aggregated categories!", 3,
95 parentScoreRes.getNumSubResults());
97 // rely on that facet value is computed as doc-score, and
98 // accordingly compare values of the two top-category results.
100 FacetResultNode[] countResNodes = resultNodesAsArray(parentCountRes);
101 FacetResultNode[] scoreResNodes = resultNodesAsArray(parentScoreRes);
103 for (int i = 0; i < scoreResNodes.length; i++) {
104 assertEquals("Ordinals differ!",
105 countResNodes[i].getOrdinal(), scoreResNodes[i].getOrdinal());
106 assertEquals("Wrong scores!",
107 constScore * countResNodes[i].getValue(),
108 scoreResNodes[i].getValue(),
113 // compute facets with certain facet requests and docs
114 private List<FacetResult> findFacets(ScoredDocIDs sDocids,
115 FacetSearchParams facetSearchParams) throws IOException {
116 FacetsAccumulator fAccumulator = new StandardFacetsAccumulator(
117 facetSearchParams, indexReader, taxoReader);
118 List<FacetResult> res = fAccumulator.accumulate(sDocids);
120 // Results are ready, printing them...
122 for (FacetResult facetResult : res) {
124 System.out.println("Res " + (i++) + ": " + facetResult);
132 public void testOutOfOrderCollectionScoringEnabled() throws Exception {
134 "when scoring enabled, out-of-order collection should not be supported",
135 ScoredDocIdCollector.create(1, true).acceptsDocsOutOfOrder());
139 public void testOutOfOrderCollectionScoringDisabled() throws Exception {
140 // This used to fail, because ScoredDocIdCollector.acceptDocsOutOfOrder
141 // returned true, even when scoring was enabled.
142 final int[] docs = new int[] { 1, 0, 2 }; // out of order on purpose
144 ScoredDocIdCollector sdic = ScoredDocIdCollector.create(docs.length, false);
146 "when scoring disabled, out-of-order collection should be supported",
147 sdic.acceptsDocsOutOfOrder());
148 for (int i = 0; i < docs.length; i++) {
149 sdic.collect(docs[i]);
152 assertEquals("expected 3 documents but got " + sdic.getScoredDocIDs().size(), 3, sdic.getScoredDocIDs().size());
153 ScoredDocIDsIterator iter = sdic.getScoredDocIDs().iterator();
155 for (int i = 0; iter.next(); i++) {
156 assertEquals("expected doc " + docs[i], docs[i], iter.getDocID());
160 /* use a scoring aggregator */
161 private FacetSearchParams sumScoreSearchParams() {
162 // this will use default faceted indexing params, not altering anything about indexing
163 FacetSearchParams res = super.getFacetedSearchParams();
164 res.addFacetRequest(new ScoreFacetRequest(new CategoryPath("root", "a"), 10));
169 protected FacetSearchParams getFacetedSearchParams() {
170 FacetSearchParams res = super.getFacetedSearchParams();
171 res.addFacetRequest(new CountFacetRequest(new CategoryPath("root","a"), 10));