Adding HumanReadableQuery with a descrition param, used for debugging print output (#12816)

This commit is contained in:
Jakub Slowinski 2023-11-18 07:21:19 +00:00 committed by GitHub
parent 48e234d988
commit b3ef869681
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 222 additions and 0 deletions

View File

@ -171,6 +171,8 @@ API Changes
* GITHUB#12180: Add TaxonomyReader#getBulkOrdinals method to more efficiently retrieve facet ordinals for multiple
FacetLabel at once. (Egor Potemkin)
* GITHUB#12816: Add HumanReadableQuery which takes a description parameter for debugging purposes. (Jakub Slowinski)
New Features
---------------------

View File

@ -0,0 +1,88 @@
/*
* 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.
*/
package org.apache.lucene.misc.search;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Weight;
/**
* A simple query wrapper for debug purposes. Behaves like the given query, but when printing to a
* string, it will prepend the description parameter to the query output.
*/
public final class HumanReadableQuery extends Query {
private final Query in;
private final String description;
/**
* Create a new HumanReadableQuery
*
* @param in the query to wrap
* @param description a human-readable description, used in toString()
*/
public HumanReadableQuery(Query in, String description) {
this.in = in;
this.description = description;
}
/**
* @return the wrapped Query
*/
public Query getWrappedQuery() {
return in;
}
/**
* @return the query description
*/
public String getDescription() {
return description;
}
@Override
public Query rewrite(IndexSearcher indexSearcher) {
return in;
}
@Override
public String toString(String field) {
return this.getDescription() + ":" + in.toString(field);
}
@Override
public void visit(QueryVisitor visitor) {
in.visit(visitor);
}
@Override
public boolean equals(Object other) {
return sameClassAs(other) && in.equals(((HumanReadableQuery) other).in);
}
@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) {
throw new UnsupportedOperationException("HumanReadableQuery does not support #createWeight()");
}
@Override
public int hashCode() {
return 31 * classHash() + in.hashCode();
}
}

View File

@ -0,0 +1,132 @@
/*
* 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.
*/
package org.apache.lucene.misc.search;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.KnnFloatVectorQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.tests.analysis.MockAnalyzer;
import org.apache.lucene.tests.analysis.MockTokenizer;
import org.apache.lucene.tests.index.RandomIndexWriter;
import org.apache.lucene.tests.search.CheckHits;
import org.apache.lucene.tests.util.English;
import org.apache.lucene.tests.util.LuceneTestCase;
import org.apache.lucene.tests.util.TestUtil;
import org.junit.AfterClass;
import org.junit.BeforeClass;
public class TestHumanReadableQuery extends LuceneTestCase {
private static IndexSearcher searcher;
private static IndexReader reader;
private static Directory directory;
private static final String field = "field";
@BeforeClass
public static void beforeClass() throws Exception {
directory = newDirectory();
RandomIndexWriter writer =
new RandomIndexWriter(
random(),
directory,
newIndexWriterConfig(new MockAnalyzer(random(), MockTokenizer.SIMPLE, true))
.setMaxBufferedDocs(TestUtil.nextInt(random(), 100, 1000))
.setMergePolicy(newLogMergePolicy()));
// writer.infoStream = System.out;
for (int i = 0; i < 1000; i++) {
Document doc = new Document();
doc.add(newTextField(field, English.intToEnglish(i), Field.Store.YES));
writer.addDocument(doc);
}
reader = writer.getReader();
searcher = newSearcher(reader);
writer.close();
}
@AfterClass
public static void afterClass() throws Exception {
reader.close();
directory.close();
searcher = null;
reader = null;
directory = null;
}
public void testHitsEqualPhraseQuery() throws Exception {
PhraseQuery pQuery = new PhraseQuery(field, "seventy", "seven");
CheckHits.checkHits(
random(),
pQuery,
field,
searcher,
new int[] {77, 177, 277, 377, 477, 577, 677, 777, 877, 977});
String description = "TestPhraseQuery";
HumanReadableQuery hQuery = new HumanReadableQuery(pQuery, description);
CheckHits.checkHits(
random(),
hQuery,
field,
searcher,
new int[] {77, 177, 277, 377, 477, 577, 677, 777, 877, 977});
assertEquals(description + ":" + pQuery, hQuery.toString());
}
public void testHitsEqualBooleanQuery() throws Exception {
BooleanQuery.Builder query = new BooleanQuery.Builder();
query.add(new TermQuery(new Term(field, "seventy")), BooleanClause.Occur.MUST);
query.add(new TermQuery(new Term(field, "seven")), BooleanClause.Occur.MUST);
BooleanQuery bQuery = query.build();
CheckHits.checkHits(
random(),
bQuery,
field,
searcher,
new int[] {
77, 177, 277, 377, 477, 577, 677, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 877,
977
});
String description = "TestBooleanQuery";
HumanReadableQuery hQuery = new HumanReadableQuery(bQuery, description);
CheckHits.checkHits(
random(),
hQuery,
field,
searcher,
new int[] {
77, 177, 277, 377, 477, 577, 677, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 877,
977
});
assertEquals(description + ":" + bQuery, hQuery.toString());
}
public void testKnnVectorQuery() {
String description = "TestingKnnVectorQuery";
KnnFloatVectorQuery kFVQ = new KnnFloatVectorQuery("f1", new float[] {0, 1}, 6);
HumanReadableQuery hQuery = new HumanReadableQuery(kFVQ, description);
assertEquals(description + ":" + kFVQ, hQuery.toString());
assertEquals(kFVQ, hQuery.getWrappedQuery());
}
}