use of com.apple.foundationdb.record.query.plan.IndexKeyValueToPartialRecord in project fdb-record-layer by FoundationDB.
the class RecordQueryPlannerSubstitutionVisitor method removeIndexFetch.
@Nullable
public static RecordQueryPlan removeIndexFetch(@Nonnull RecordMetaData recordMetaData, @Nonnull PlannableIndexTypes indexTypes, @Nullable KeyExpression commonPrimaryKey, @Nonnull RecordQueryPlan plan, @Nonnull Set<KeyExpression> requiredFields) {
if (plan instanceof RecordQueryPlanWithIndex) {
RecordQueryPlanWithIndex indexPlan = (RecordQueryPlanWithIndex) plan;
Index index = recordMetaData.getIndex(indexPlan.getIndexName());
final Collection<RecordType> recordTypes = recordMetaData.recordTypesForIndex(index);
if (recordTypes.size() != 1) {
return null;
}
final RecordType recordType = Iterables.getOnlyElement(recordTypes);
AvailableFields fieldsFromIndex = AvailableFields.fromIndex(recordType, index, indexTypes, commonPrimaryKey);
Set<KeyExpression> fields = new HashSet<>(requiredFields);
if (commonPrimaryKey != null) {
// Need the primary key, even if it wasn't one of the explicit result fields.
fields.addAll(commonPrimaryKey.normalizeKeyForPositions());
}
if (fieldsFromIndex.containsAll(fields)) {
final IndexKeyValueToPartialRecord keyValueToPartialRecord = fieldsFromIndex.buildIndexKeyValueToPartialRecord(recordType).build();
if (keyValueToPartialRecord != null) {
return new RecordQueryCoveringIndexPlan(indexPlan, recordType.getName(), fieldsFromIndex, keyValueToPartialRecord);
}
}
} else if (plan instanceof RecordQueryFetchFromPartialRecordPlan) {
RecordQueryFetchFromPartialRecordPlan fetchPlan = (RecordQueryFetchFromPartialRecordPlan) plan;
if (fetchPlan.getChild().getAvailableFields().containsAll(requiredFields)) {
return ((RecordQueryFetchFromPartialRecordPlan) plan).getChild();
}
}
return null;
}
use of com.apple.foundationdb.record.query.plan.IndexKeyValueToPartialRecord in project fdb-record-layer by FoundationDB.
the class LuceneIndexTest method searchForSpellcheckForGroupedRecord.
@Test
void searchForSpellcheckForGroupedRecord() throws Exception {
try (FDBRecordContext context = openContext()) {
openRecordStore(context, metaDataBuilder -> {
metaDataBuilder.removeIndex(TextIndexTestUtils.SIMPLE_DEFAULT_NAME);
metaDataBuilder.addIndex(MAP_DOC, MAP_ON_VALUE_INDEX);
});
FDBStoredRecord<Message> fdbRecord = recordStore.saveRecord(createMultiEntryMapDoc(1623L, ENGINEER_JOKE, "sampleTextPhrase", WAYLON, "sampleTextSong", 2));
List<IndexEntry> indexEntries = recordStore.scanIndex(MAP_ON_VALUE_INDEX, IndexScanType.BY_LUCENE_SPELLCHECK, TupleRange.allOf(Tuple.from("Visin", "sampleTextPhrase")), null, ScanProperties.FORWARD_SCAN).asList().get();
assertEquals(1, indexEntries.size());
IndexEntry indexEntry = indexEntries.get(0);
assertEquals(0.8F, indexEntry.getValue().get(0));
Descriptors.Descriptor recordDescriptor = TestRecordsTextProto.MapDocument.getDescriptor();
IndexKeyValueToPartialRecord toPartialRecord = LuceneIndexQueryPlan.getToPartialRecord(MAP_ON_VALUE_INDEX, fdbRecord.getRecordType(), IndexScanType.BY_LUCENE_SPELLCHECK);
Message message = toPartialRecord.toRecord(recordDescriptor, indexEntry);
Descriptors.FieldDescriptor entryDescriptor = recordDescriptor.findFieldByName("entry");
Message entry = (Message) message.getRepeatedField(entryDescriptor, 0);
Descriptors.FieldDescriptor keyDescriptor = entryDescriptor.getMessageType().findFieldByName("key");
Descriptors.FieldDescriptor valueDescriptor = entryDescriptor.getMessageType().findFieldByName("value");
// TODO: This seems like the wrong field string to return. I'm not sure what to do here
assertEquals("sampleTextPhrase", entry.getField(keyDescriptor));
assertEquals("vision", entry.getField(valueDescriptor));
// assertEquals(1, context.getTimer().getCounter(FDBStoreTimer.Counts.LUCENE_SCAN_MATCHED_AUTO_COMPLETE_SUGGESTIONS).getCount());
// assertEntriesAndSegmentInfoStoredInCompoundFile(recordStore.indexSubspace(MAP_ON_VALUE_INDEX_WITH_AUTO_COMPLETE).subspace(Tuple.from("sampleTextPhrase")), context, "_0.cfs", true);
}
}
use of com.apple.foundationdb.record.query.plan.IndexKeyValueToPartialRecord in project fdb-record-layer by FoundationDB.
the class LuceneIndexQueryPlan method getToPartialRecord.
/**
* Get the {@link IndexKeyValueToPartialRecord} instance for an {@link IndexEntry} representing a result of Lucene auto-complete suggestion.
* The partial record contains the suggestion in the field where it is indexed from, and the grouping keys if there are any.
*/
@VisibleForTesting
public static IndexKeyValueToPartialRecord getToPartialRecord(@Nonnull Index index, @Nonnull RecordType recordType, @Nonnull IndexScanType scanType) {
final IndexKeyValueToPartialRecord.Builder builder = IndexKeyValueToPartialRecord.newBuilder(recordType);
KeyExpression root = index.getRootExpression();
if (root instanceof GroupingKeyExpression) {
KeyExpression groupingKey = ((GroupingKeyExpression) root).getGroupingSubKey();
for (int i = 0; i < groupingKey.getColumnSize(); i++) {
AvailableFields.addCoveringField(groupingKey, AvailableFields.FieldData.of(IndexKeyValueToPartialRecord.TupleSource.KEY, i), builder);
}
}
builder.addRequiredMessageFields();
if (!builder.isValid(true)) {
throw new RecordCoreException("Missing required field for result record").addLogInfo(LogMessageKeys.INDEX_NAME, index.getName()).addLogInfo(LogMessageKeys.RECORD_TYPE, recordType.getName()).addLogInfo(LogMessageKeys.SCAN_TYPE, scanType);
}
builder.addRegularCopier(new LuceneIndexKeyValueToPartialRecordUtils.LuceneAutoCompleteCopier());
return builder.build();
}
use of com.apple.foundationdb.record.query.plan.IndexKeyValueToPartialRecord in project fdb-record-layer by FoundationDB.
the class LuceneIndexTest method searchForAutoCompleteForGroupedRecord.
@Test
void searchForAutoCompleteForGroupedRecord() throws Exception {
try (FDBRecordContext context = openContext()) {
openRecordStore(context, metaDataBuilder -> {
metaDataBuilder.removeIndex(TextIndexTestUtils.SIMPLE_DEFAULT_NAME);
metaDataBuilder.addIndex(MAP_DOC, MAP_ON_VALUE_INDEX_WITH_AUTO_COMPLETE);
});
FDBStoredRecord<Message> fdbRecord = recordStore.saveRecord(createMultiEntryMapDoc(1623L, ENGINEER_JOKE, "sampleTextPhrase", WAYLON, "sampleTextSong", 2));
List<IndexEntry> indexEntries = recordStore.scanIndex(MAP_ON_VALUE_INDEX_WITH_AUTO_COMPLETE, IndexScanType.BY_LUCENE_AUTO_COMPLETE, TupleRange.allOf(Tuple.from("Vision", "sampleTextPhrase")), null, ScanProperties.FORWARD_SCAN).asList().get();
assertEquals(1, indexEntries.size());
IndexEntry indexEntry = indexEntries.get(0);
Descriptors.Descriptor recordDescriptor = TestRecordsTextProto.MapDocument.getDescriptor();
IndexKeyValueToPartialRecord toPartialRecord = LuceneIndexQueryPlan.getToPartialRecord(MAP_ON_VALUE_INDEX_WITH_AUTO_COMPLETE, fdbRecord.getRecordType(), IndexScanType.BY_LUCENE_AUTO_COMPLETE);
Message message = toPartialRecord.toRecord(recordDescriptor, indexEntry);
Descriptors.FieldDescriptor entryDescriptor = recordDescriptor.findFieldByName("entry");
Message entry = (Message) message.getRepeatedField(entryDescriptor, 0);
Descriptors.FieldDescriptor keyDescriptor = entryDescriptor.getMessageType().findFieldByName("key");
Descriptors.FieldDescriptor valueDescriptor = entryDescriptor.getMessageType().findFieldByName("value");
assertEquals("sampleTextPhrase", entry.getField(keyDescriptor));
assertEquals(ENGINEER_JOKE, entry.getField(valueDescriptor));
assertEquals(1, context.getTimer().getCounter(FDBStoreTimer.Counts.LUCENE_SCAN_MATCHED_AUTO_COMPLETE_SUGGESTIONS).getCount());
assertEntriesAndSegmentInfoStoredInCompoundFile(AutoCompleteSuggesterCommitCheckAsync.getSuggestionIndexSubspace(recordStore.indexSubspace(MAP_ON_VALUE_INDEX_WITH_AUTO_COMPLETE), Tuple.from("sampleTextPhrase")), context, "_0.cfs", true);
}
}
use of com.apple.foundationdb.record.query.plan.IndexKeyValueToPartialRecord in project fdb-record-layer by FoundationDB.
the class QueryPlanUtils method getCoveringIndexEntryToPartialRecordFunction.
/**
* The method to get a function from an {@link IndexEntry} to a {@link FDBQueriedRecord} representing a partial record.
*/
@SuppressWarnings("unchecked")
public static <M extends Message> Function<IndexEntry, FDBQueriedRecord<M>> getCoveringIndexEntryToPartialRecordFunction(@Nonnull final FDBRecordStoreBase<M> store, @Nonnull final String recordTypeName, @Nonnull final String indexName, @Nonnull final IndexKeyValueToPartialRecord toRecord, @Nonnull final IndexScanType scanType) {
final RecordMetaData metaData = store.getRecordMetaData();
final RecordType recordType = metaData.getRecordType(recordTypeName);
final Index index = metaData.getIndex(indexName);
final Descriptors.Descriptor recordDescriptor = recordType.getDescriptor();
boolean hasPrimaryKey = scanType != IndexScanType.BY_GROUP && scanType != IndexScanType.BY_LUCENE_AUTO_COMPLETE && scanType != IndexScanType.BY_LUCENE_SPELLCHECK;
return indexEntry -> store.coveredIndexQueriedRecord(index, indexEntry, recordType, (M) toRecord.toRecord(recordDescriptor, indexEntry), hasPrimaryKey);
}
Aggregations