Search in sources :

Example 36 with IndexEntry

use of com.apple.foundationdb.record.IndexEntry in project fdb-record-layer by FoundationDB.

the class LuceneIndexTest method searchForAutoCompleteWithContinueTyping.

@Test
void searchForAutoCompleteWithContinueTyping() throws Exception {
    try (FDBRecordContext context = openContext()) {
        addIndexAndSaveRecordForAutoComplete(context, false);
        List<IndexEntry> results = recordStore.scanIndex(SIMPLE_TEXT_WITH_AUTO_COMPLETE, IndexScanType.BY_LUCENE_AUTO_COMPLETE, TupleRange.allOf(Tuple.from("good mor")), null, ScanProperties.FORWARD_SCAN).asList().get();
        // Assert only 1 suggestion returned
        assertEquals(1, results.size());
        // Assert the suggestion's key and field
        IndexEntry result = results.get(0);
        assertEquals("Good morning", result.getKey().get(result.getKeySize() - 1));
        assertEquals("text", result.getKey().get(result.getKeySize() - 2));
        assertEquals(1, context.getTimer().getCounter(FDBStoreTimer.Counts.LUCENE_SCAN_MATCHED_AUTO_COMPLETE_SUGGESTIONS).getCount());
        assertEntriesAndSegmentInfoStoredInCompoundFile(AutoCompleteSuggesterCommitCheckAsync.getSuggestionIndexSubspace(recordStore.indexSubspace(SIMPLE_TEXT_WITH_AUTO_COMPLETE), TupleHelpers.EMPTY), context, "_0.cfs", true);
    }
}
Also used : FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) IndexEntry(com.apple.foundationdb.record.IndexEntry) Test(org.junit.jupiter.api.Test)

Example 37 with IndexEntry

use of com.apple.foundationdb.record.IndexEntry in project fdb-record-layer by FoundationDB.

the class LuceneSpellcheckRecordCursor method spellcheck.

private void spellcheck() throws IOException {
    if (spellcheckSuggestions != null) {
        return;
    }
    long startTime = System.nanoTime();
    indexReader = getIndexReader();
    List<Suggestion> suggestionResults = new ArrayList<>();
    for (String field : fields) {
        // collect all suggestions across all given fields or across all fields depending on user options.
        Arrays.stream(spellchecker.suggestSimilar(new Term(field, wordToSpellCheck), limit, indexReader)).map(suggestion -> new Suggestion(field, suggestion)).forEach(suggestionResults::add);
    }
    spellcheckSuggestions = suggestionResults.stream().collect(Collectors.toMap(suggestion -> suggestion.suggestWord.string, Function.identity(), // TODO: For arnaud, are we checking for a merge on ALL suggested words against eachother?
    LuceneSpellcheckRecordCursor::mergeTwoSuggestWords)).values().stream().sorted(comparing((Suggestion s) -> s.suggestWord.score).reversed().thenComparing(comparing((Suggestion s) -> s.suggestWord.freq).reversed()).thenComparing(s -> s.suggestWord.string)).limit(limit).map(suggestion -> new IndexEntry(state.index, Tuple.from(groupingKey == null || groupingKey.isEmpty() ? "" : groupingKey.getString(0), suggestion.indexField, suggestion.suggestWord.string), Tuple.from(suggestion.suggestWord.score))).collect(Collectors.toList());
    if (timer != null) {
        timer.recordSinceNanoTime(FDBStoreTimer.Events.LUCENE_SPELLCHECK_SCAN, startTime);
        timer.increment(FDBStoreTimer.Counts.LUCENE_SCAN_SPELLCHECKER_SUGGESTIONS, spellcheckSuggestions.size());
    }
}
Also used : IndexEntry(com.apple.foundationdb.record.IndexEntry) Arrays(java.util.Arrays) LogMessageKeys(com.apple.foundationdb.util.LogMessageKeys) IndexMaintainerState(com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerState) Term(org.apache.lucene.index.Term) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) DirectoryCommitCheckAsync.getOrCreateDirectoryCommitCheckAsync(com.apple.foundationdb.record.lucene.DirectoryCommitCheckAsync.getOrCreateDirectoryCommitCheckAsync) Function(java.util.function.Function) ArrayList(java.util.ArrayList) RecordCursorVisitor(com.apple.foundationdb.record.RecordCursorVisitor) Tuple(com.apple.foundationdb.tuple.Tuple) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) ScanProperties(com.apple.foundationdb.record.ScanProperties) Comparator.comparing(java.util.Comparator.comparing) Nonnull(javax.annotation.Nonnull) ByteArrayContinuation(com.apple.foundationdb.record.ByteArrayContinuation) Nullable(javax.annotation.Nullable) SuggestWord(org.apache.lucene.search.spell.SuggestWord) Logger(org.slf4j.Logger) RecordCursorContinuation(com.apple.foundationdb.record.RecordCursorContinuation) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) Executor(java.util.concurrent.Executor) DirectoryReader(org.apache.lucene.index.DirectoryReader) DirectSpellChecker(org.apache.lucene.search.spell.DirectSpellChecker) IOUtils(org.apache.lucene.util.IOUtils) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) BaseCursor(com.apple.foundationdb.record.cursors.BaseCursor) ByteString(com.google.protobuf.ByteString) List(java.util.List) RecordCursorProto(com.apple.foundationdb.record.RecordCursorProto) IndexReader(org.apache.lucene.index.IndexReader) IndexWriterCommitCheckAsync.getIndexWriterCommitCheckAsync(com.apple.foundationdb.record.lucene.IndexWriterCommitCheckAsync.getIndexWriterCommitCheckAsync) ArrayList(java.util.ArrayList) IndexEntry(com.apple.foundationdb.record.IndexEntry) ByteString(com.google.protobuf.ByteString) Term(org.apache.lucene.index.Term)

Example 38 with IndexEntry

use of com.apple.foundationdb.record.IndexEntry in project fdb-record-layer by FoundationDB.

the class FDBRecordStoreIndexTest method testIndexOrphanValidationByIterations.

@Test
public void testIndexOrphanValidationByIterations() throws Exception {
    Set<IndexEntry> expectedInvalidEntries = setUpIndexOrphanValidation();
    // Validate the index. Should only return the index entry that has no associated record.
    final Random random = new Random();
    byte[] continuation = null;
    Set<IndexEntry> results = new HashSet<>();
    do {
        // 1, 2, 3, or 4.
        int limit = random.nextInt(4) + 1;
        try (FDBRecordContext context = openContext()) {
            uncheckedOpenSimpleRecordStore(context);
            final Index index = recordStore.getRecordMetaData().getIndex("MySimpleRecord$str_value_indexed");
            final RecordCursorIterator<InvalidIndexEntry> cursor = recordStore.getIndexMaintainer(index).validateEntries(continuation, null).limitRowsTo(limit).asIterator();
            while (cursor.hasNext()) {
                InvalidIndexEntry invalidIndexEntry = cursor.next();
                assertEquals(InvalidIndexEntry.Reasons.ORPHAN, invalidIndexEntry.getReason());
                IndexEntry entry = invalidIndexEntry.getEntry();
                assertFalse(results.contains(entry), "Entry " + entry + " is duplicated");
                results.add(entry);
            }
            continuation = cursor.getContinuation();
            commit(context);
        }
    } while (continuation != null);
    assertEquals(expectedInvalidEntries, results, "Validation should return the index entry that has no associated record.");
}
Also used : Random(java.util.Random) InvalidIndexEntry(com.apple.foundationdb.record.provider.foundationdb.indexes.InvalidIndexEntry) IndexEntry(com.apple.foundationdb.record.IndexEntry) Index(com.apple.foundationdb.record.metadata.Index) InvalidIndexEntry(com.apple.foundationdb.record.provider.foundationdb.indexes.InvalidIndexEntry) HashSet(java.util.HashSet) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Test(org.junit.jupiter.api.Test)

Example 39 with IndexEntry

use of com.apple.foundationdb.record.IndexEntry in project fdb-record-layer by FoundationDB.

the class FunctionKeyIndexTest method testFanOutFunction.

@Test
public void testFanOutFunction() throws Exception {
    Index index = new Index("str_fields_index", function("indexStrFields"), IndexTypes.VALUE);
    Records records = Records.create();
    records.add(0, "a,b,c");
    for (int i = 1; i < 10; i++) {
        records.add(i, "a,b,c_" + i, "a_" + i + ",b,c", "a,b_" + i + ",c");
    }
    saveRecords(records, index);
    try (FDBRecordContext context = openContext()) {
        openRecordStore(context, index);
        List<IndexEntry> keyValues = getIndexKeyValues(recordStore, index, IndexScanType.BY_VALUE);
        int count = 0;
        for (IndexEntry kv : keyValues) {
            Tuple key = kv.getKey();
            assertEquals(4, key.size(), "Wrong key length");
            assertTrue(key.getString(0).startsWith("a"), "Invalid value in first key element: " + key.get(0));
            assertTrue(key.getString(1).startsWith("b"), "Invalid value in second key element: " + key.get(1));
            assertTrue(key.getString(2).startsWith("c"), "Invalid value in third key element: " + key.get(2));
            ++count;
        }
        assertEquals(28, count, "Too few index keys");
    }
}
Also used : IndexEntry(com.apple.foundationdb.record.IndexEntry) Index(com.apple.foundationdb.record.metadata.Index) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 40 with IndexEntry

use of com.apple.foundationdb.record.IndexEntry in project fdb-record-layer by FoundationDB.

the class SyntheticRecordPlannerTest method joinIndex.

@Test
public void joinIndex() throws Exception {
    metaDataBuilder.addIndex("MySimpleRecord", "other_rec_no");
    final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("Simple_Other");
    joined.addConstituent("simple", "MySimpleRecord");
    joined.addConstituent("other", "MyOtherRecord");
    joined.addJoin("simple", "other_rec_no", "other", "rec_no");
    metaDataBuilder.addIndex(joined, new Index("simple.str_value_other.num_value_3", concat(field("simple").nest("str_value"), field("other").nest("num_value_3"))));
    try (FDBRecordContext context = openContext()) {
        final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).create();
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < i; j++) {
                TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
                simple.setRecNo(100 * i + j).setOtherRecNo(1000 + i);
                simple.setStrValue((i + j) % 2 == 0 ? "even" : "odd");
                recordStore.saveRecord(simple.build());
            }
            TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
            other.setRecNo(1000 + i);
            other.setNumValue3(i);
            recordStore.saveRecord(other.build());
        }
        context.commit();
    }
    try (FDBRecordContext context = openContext()) {
        final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
        final Index index = recordStore.getRecordMetaData().getIndex("simple.str_value_other.num_value_3");
        final TupleRange range = new ScanComparisons.Builder().addEqualityComparison(new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, "even")).addInequalityComparison(new Comparisons.SimpleComparison(Comparisons.Type.GREATER_THAN, 1)).build().toTupleRange();
        List<Tuple> expected1 = Arrays.asList(Tuple.from("even", 2, -1, Tuple.from(200), Tuple.from(1002)));
        List<Tuple> results1 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
        assertEquals(expected1, results1);
        FDBStoredRecord<Message> record = recordStore.loadRecord(Tuple.from(201));
        TestRecordsJoinIndexProto.MySimpleRecord.Builder recordBuilder = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder().mergeFrom(record.getRecord());
        recordBuilder.setStrValue("even");
        recordStore.saveRecord(recordBuilder.build());
        List<Tuple> expected2 = Arrays.asList(Tuple.from("even", 2, -1, Tuple.from(200), Tuple.from(1002)), Tuple.from("even", 2, -1, Tuple.from(201), Tuple.from(1002)));
        List<Tuple> results2 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
        assertEquals(expected2, results2);
        recordStore.deleteRecord(Tuple.from(1002));
        List<Tuple> expected3 = Arrays.asList();
        List<Tuple> results3 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
        assertEquals(expected3, results3);
    }
}
Also used : Message(com.google.protobuf.Message) JoinedRecordTypeBuilder(com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) IndexEntry(com.apple.foundationdb.record.IndexEntry) Index(com.apple.foundationdb.record.metadata.Index) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) JoinedRecordTypeBuilder(com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) TupleRange(com.apple.foundationdb.record.TupleRange) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Aggregations

IndexEntry (com.apple.foundationdb.record.IndexEntry)74 Tuple (com.apple.foundationdb.tuple.Tuple)41 Nonnull (javax.annotation.Nonnull)37 Index (com.apple.foundationdb.record.metadata.Index)34 Test (org.junit.jupiter.api.Test)34 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)32 Message (com.google.protobuf.Message)32 ScanProperties (com.apple.foundationdb.record.ScanProperties)29 ArrayList (java.util.ArrayList)29 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)28 TupleRange (com.apple.foundationdb.record.TupleRange)28 List (java.util.List)28 Nullable (javax.annotation.Nullable)27 IndexScanType (com.apple.foundationdb.record.IndexScanType)24 RecordCursor (com.apple.foundationdb.record.RecordCursor)22 CompletableFuture (java.util.concurrent.CompletableFuture)21 Collectors (java.util.stream.Collectors)21 ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)20 TupleHelpers (com.apple.foundationdb.tuple.TupleHelpers)20 FDBStoreTimer (com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer)19