-
Notifications
You must be signed in to change notification settings - Fork 25.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Handle MatchNoDocsQuery in span query wrappers (#34106)
* Handle MatchNoDocsQuery in span query wrappers This change adds a new SpanMatchNoDocsQuery query that replaces MatchNoDocsQuery in the span query wrappers. The `wildcard` query now returns MatchNoDocsQuery if the target field is not in the mapping (#34093) so we need the equivalent span query in order to be able to pass it to other span wrappers. Closes #34105
- Loading branch information
Showing
12 changed files
with
233 additions
and
4 deletions.
There are no files selected for viewing
87 changes: 87 additions & 0 deletions
87
server/src/main/java/org/apache/lucene/queries/SpanMatchNoDocsQuery.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* | ||
* Licensed to Elasticsearch under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch 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.queries; | ||
|
||
import org.apache.lucene.index.LeafReaderContext; | ||
import org.apache.lucene.index.Term; | ||
import org.apache.lucene.index.TermStates; | ||
import org.apache.lucene.search.IndexSearcher; | ||
import org.apache.lucene.search.ScoreMode; | ||
import org.apache.lucene.search.spans.SpanQuery; | ||
import org.apache.lucene.search.spans.SpanWeight; | ||
import org.apache.lucene.search.spans.Spans; | ||
|
||
import java.io.IOException; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
/** | ||
* A {@link SpanQuery} that matches no documents. | ||
*/ | ||
public class SpanMatchNoDocsQuery extends SpanQuery { | ||
private final String field; | ||
private final String reason; | ||
|
||
public SpanMatchNoDocsQuery(String field, String reason) { | ||
this.field = field; | ||
this.reason = reason; | ||
} | ||
|
||
@Override | ||
public String getField() { | ||
return field; | ||
} | ||
|
||
@Override | ||
public String toString(String field) { | ||
return "SpanMatchNoDocsQuery(\"" + reason + "\")"; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
return sameClassAs(o); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return classHash(); | ||
} | ||
|
||
@Override | ||
public SpanWeight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException { | ||
return new SpanWeight(this, searcher, Collections.emptyMap(), boost) { | ||
@Override | ||
public void extractTermStates(Map<Term, TermStates> contexts) {} | ||
|
||
@Override | ||
public Spans getSpans(LeafReaderContext ctx, Postings requiredPostings) { | ||
return null; | ||
} | ||
|
||
@Override | ||
public void extractTerms(Set<Term> terms) {} | ||
|
||
@Override | ||
public boolean isCacheable(LeafReaderContext ctx) { | ||
return true; | ||
} | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
server/src/test/java/org/apache/lucene/queries/SpanMatchNoDocsQueryTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
* Licensed to Elasticsearch under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch 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.queries; | ||
|
||
import org.apache.lucene.analysis.Analyzer; | ||
import org.apache.lucene.analysis.MockAnalyzer; | ||
import org.apache.lucene.document.Document; | ||
import org.apache.lucene.document.Field; | ||
import org.apache.lucene.index.DirectoryReader; | ||
import org.apache.lucene.index.IndexReader; | ||
import org.apache.lucene.index.IndexWriter; | ||
import org.apache.lucene.index.Term; | ||
import org.apache.lucene.search.IndexSearcher; | ||
import org.apache.lucene.search.Query; | ||
import org.apache.lucene.search.QueryUtils; | ||
import org.apache.lucene.search.ScoreDoc; | ||
import org.apache.lucene.search.spans.SpanNearQuery; | ||
import org.apache.lucene.search.spans.SpanOrQuery; | ||
import org.apache.lucene.search.spans.SpanQuery; | ||
import org.apache.lucene.search.spans.SpanTermQuery; | ||
import org.apache.lucene.store.Directory; | ||
import org.elasticsearch.test.ESTestCase; | ||
|
||
import java.io.IOException; | ||
|
||
public class SpanMatchNoDocsQueryTests extends ESTestCase { | ||
public void testSimple() throws Exception { | ||
SpanMatchNoDocsQuery query = new SpanMatchNoDocsQuery("field", "a good reason"); | ||
assertEquals(query.toString(), "SpanMatchNoDocsQuery(\"a good reason\")"); | ||
Query rewrite = query.rewrite(null); | ||
assertTrue(rewrite instanceof SpanMatchNoDocsQuery); | ||
assertEquals(rewrite.toString(), "SpanMatchNoDocsQuery(\"a good reason\")"); | ||
} | ||
|
||
public void testQuery() throws Exception { | ||
Directory dir = newDirectory(); | ||
Analyzer analyzer = new MockAnalyzer(random()); | ||
IndexWriter iw = new IndexWriter(dir, | ||
newIndexWriterConfig(analyzer).setMaxBufferedDocs(2).setMergePolicy(newLogMergePolicy())); | ||
addDoc("one", iw); | ||
addDoc("two", iw); | ||
addDoc("three", iw); | ||
IndexReader ir = DirectoryReader.open(iw); | ||
IndexSearcher searcher = new IndexSearcher(ir); | ||
|
||
Query query = new SpanMatchNoDocsQuery("unkwown", "field not found"); | ||
assertEquals(searcher.count(query), 0); | ||
|
||
ScoreDoc[] hits; | ||
hits = searcher.search(query, 1000).scoreDocs; | ||
assertEquals(0, hits.length); | ||
assertEquals(query.toString(), "SpanMatchNoDocsQuery(\"field not found\")"); | ||
|
||
SpanOrQuery orQuery = new SpanOrQuery( | ||
new SpanMatchNoDocsQuery("unknown", "field not found"), | ||
new SpanTermQuery(new Term("unknown", "one")) | ||
); | ||
assertEquals(searcher.count(orQuery), 0); | ||
hits = searcher.search(orQuery, 1000).scoreDocs; | ||
assertEquals(0, hits.length); | ||
|
||
orQuery = new SpanOrQuery( | ||
new SpanMatchNoDocsQuery("key", "a good reason"), | ||
new SpanTermQuery(new Term("key", "one")) | ||
); | ||
assertEquals(searcher.count(orQuery), 1); | ||
hits = searcher.search(orQuery, 1000).scoreDocs; | ||
assertEquals(1, hits.length); | ||
Query rewrite = orQuery.rewrite(ir); | ||
assertEquals(rewrite, orQuery); | ||
|
||
SpanNearQuery nearQuery = new SpanNearQuery( | ||
new SpanQuery[] {new SpanMatchNoDocsQuery("same", ""), new SpanMatchNoDocsQuery("same", "")}, | ||
0, true); | ||
assertEquals(searcher.count(nearQuery), 0); | ||
hits = searcher.search(nearQuery, 1000).scoreDocs; | ||
assertEquals(0, hits.length); | ||
rewrite = nearQuery.rewrite(ir); | ||
assertEquals(rewrite, nearQuery); | ||
|
||
iw.close(); | ||
ir.close(); | ||
dir.close(); | ||
} | ||
|
||
public void testEquals() { | ||
Query q1 = new SpanMatchNoDocsQuery("key1", "one"); | ||
Query q2 = new SpanMatchNoDocsQuery("key2", "two"); | ||
assertTrue(q1.equals(q2)); | ||
QueryUtils.check(q1); | ||
} | ||
|
||
private void addDoc(String text, IndexWriter iw) throws IOException { | ||
Document doc = new Document(); | ||
Field f = newTextField("key", text, Field.Store.YES); | ||
doc.add(f); | ||
iw.addDocument(doc); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters