Index: lucene/core/src/test/org/apache/lucene/search/spans/TestNestedSpanNearQuery.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- lucene/core/src/test/org/apache/lucene/search/spans/TestNestedSpanNearQuery.java (revision ) +++ lucene/core/src/test/org/apache/lucene/search/spans/TestNestedSpanNearQuery.java (revision ) @@ -0,0 +1,108 @@ +package org.apache.lucene.search.spans; + +/* + * 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. + */ + +import java.io.IOException; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.CharArraySet; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.RAMDirectory; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class TestNestedSpanNearQuery { + private static final String FIELD_NM = "text"; + + private Analyzer analyzer = new StandardAnalyzer(CharArraySet.EMPTY_SET); + private Directory directory; + + @Before + public void setup() throws Exception { + directory = new RAMDirectory(); + } + + protected static void addDocument(IndexWriter writer, String field, String value) throws IOException { + Document document = new Document(); + document.add(new TextField(field, value, Field.Store.YES)); + writer.addDocument(document); + } + + @Test + public void nestedSpanNearQueryWithRepeatingGroupsShouldFindDocumentAnyOrder() throws Exception { + IndexWriterConfig conf = new IndexWriterConfig(analyzer); + IndexWriter indexWriter = new IndexWriter(directory, conf); + String value = "w x a b c d d b c e y z"; + addDocument(indexWriter, FIELD_NM, value); + indexWriter.close(); + + Query query = createNestedSpanQuery("a b c d d b c e", false); + IndexReader reader = DirectoryReader.open(directory); + IndexSearcher searcher = new IndexSearcher(reader); + TopDocs topDocs = searcher.search(query, 10); + assertEquals(1, topDocs.totalHits); + } + + @Test + public void nestedSpanNearQueryWithRepeatingGroupsShouldFindDocumentInOrder() throws Exception { + IndexWriterConfig conf = new IndexWriterConfig(analyzer); + IndexWriter indexWriter = new IndexWriter(directory, conf); + String value = "w x a b c d d b c e y z"; + addDocument(indexWriter, FIELD_NM, value); + indexWriter.close(); + + Query query = createNestedSpanQuery("a b c d d b c e", true); + IndexReader reader = DirectoryReader.open(directory); + IndexSearcher searcher = new IndexSearcher(reader); + TopDocs topDocs = searcher.search(query, 10); + assertEquals(1, topDocs.totalHits); + } + + private SpanQuery createNestedSpanQuery(String queryStr, boolean inOrder) throws IOException { + String[] splits = queryStr.split(" "); + SpanQuery parentClause = null; + SpanQuery spanQuery = null; + for (int i = 0; i < splits.length; i++) { + SpanTermQuery spanTermQuery = new SpanTermQuery(new Term(FIELD_NM, splits[i].toLowerCase())); + SpanQuery[] clauses = parentClause == null ? new SpanQuery[]{spanTermQuery} : new SpanQuery[]{parentClause, spanTermQuery}; + if (clauses.length > 1) { + spanQuery = new SpanNearQuery(clauses, 2, inOrder); + } else { + spanQuery = spanTermQuery; + } + parentClause = spanQuery; + } + return spanQuery; + } + +} +