Forráskód Böngészése

fix IndexOutOfBoundsException on _all field without tokens and keyword analyzer

fix AllEntries to only compute boost when there are actually some Entries available for the _all field

Closes #4771
Matthias Wahl 11 éve
szülő
commit
c42f7708be

+ 15 - 12
src/main/java/org/elasticsearch/common/lucene/all/AllEntries.java

@@ -145,20 +145,23 @@ public class AllEntries extends Reader {
 
     // compute the boost for a token with the given startOffset
     public float boost(int startOffset) {
-        int lo = 0, hi = entries.size() - 1;
-        while (lo <= hi) {
-            final int mid = (lo + hi) >>> 1;
-            final int midOffset = entries.get(mid).startOffset();
-            if (startOffset < midOffset) {
-                hi = mid - 1;
-            } else {
-                lo = mid + 1;
+        if (!entries.isEmpty()) {
+            int lo = 0, hi = entries.size() - 1;
+            while (lo <= hi) {
+                final int mid = (lo + hi) >>> 1;
+                final int midOffset = entries.get(mid).startOffset();
+                if (startOffset < midOffset) {
+                    hi = mid - 1;
+                } else {
+                    lo = mid + 1;
+                }
             }
+            final int index = Math.max(0, hi); // protection against broken token streams
+            assert entries.get(index).startOffset() <= startOffset;
+            assert index == entries.size() - 1 || entries.get(index + 1).startOffset() > startOffset;
+            return entries.get(index).boost();
         }
-        final int index = Math.max(0, hi); // protection against broken token streams
-        assert entries.get(index).startOffset() <= startOffset;
-        assert index == entries.size() - 1 || entries.get(index + 1).startOffset() > startOffset;
-        return entries.get(index).boost();
+        return 1.0f;
     }
 
     @Override

+ 21 - 0
src/test/java/org/elasticsearch/common/lucene/all/SimpleAllTests.java

@@ -318,4 +318,25 @@ public class SimpleAllTests extends ElasticsearchTestCase {
 
         indexWriter.close();
     }
+
+    @Test
+    public void testNoTokensWithKeywordAnalyzer() throws Exception {
+        Directory dir = new RAMDirectory();
+        IndexWriter indexWriter = new IndexWriter(dir, new IndexWriterConfig(Lucene.VERSION, Lucene.KEYWORD_ANALYZER));
+
+        Document doc = new Document();
+        doc.add(new Field("_id", "1", StoredField.TYPE));
+        AllEntries allEntries = new AllEntries();
+        allEntries.reset();
+        doc.add(new TextField("_all", AllTokenStream.allTokenStream("_all", allEntries, Lucene.KEYWORD_ANALYZER)));
+
+        indexWriter.addDocument(doc);
+
+        IndexReader reader = DirectoryReader.open(indexWriter, true);
+        IndexSearcher searcher = new IndexSearcher(reader);
+
+        TopDocs docs = searcher.search(new MatchAllDocsQuery(), 10);
+        assertThat(docs.totalHits, equalTo(1));
+        assertThat(docs.scoreDocs[0].doc, equalTo(0));
+    }
 }

+ 9 - 0
src/test/java/org/elasticsearch/search/query/SimpleQueryTests.java

@@ -2024,4 +2024,13 @@ public class SimpleQueryTests extends ElasticsearchIntegrationTest {
         assertHitCount(searchResponse, 1l);
         assertFirstHit(searchResponse, hasId("4"));
     }
+
+    @Test
+    public void testSearchEmptyDoc() {
+        prepareCreate("test").setSettings("{\"index.analysis.analyzer.default.type\":\"keyword\"}").get();
+        client().prepareIndex("test", "type1", "1").setSource("{}").get();
+        refresh();
+        assertHitCount(client().prepareSearch().setQuery(matchAllQuery()).get(), 1l);
+    }
+
 }