use of com.apple.foundationdb.record.provider.foundationdb.indexes.TextIndexTestUtils.SIMPLE_DOC in project fdb-record-layer by FoundationDB.
the class TextIndexTest method querySimpleDocumentsMaybeCovering.
@Test
public void querySimpleDocumentsMaybeCovering() throws Exception {
final List<SimpleDocument> documents = TextIndexTestUtils.toSimpleDocuments(Arrays.asList(TextSamples.ANGSTROM, TextSamples.AETHELRED, TextSamples.ROMEO_AND_JULIET_PROLOGUE, TextSamples.FRENCH));
try (FDBRecordContext context = openContext()) {
openRecordStore(context);
documents.forEach(recordStore::saveRecord);
final QueryComponent filter1 = Query.field("text").text().containsPhrase("civil blood makes civil hands unclean");
final Comparisons.Comparison comparison1 = new Comparisons.TextComparison(Comparisons.Type.TEXT_CONTAINS_PHRASE, "civil blood makes civil hands unclean", null, DefaultTextTokenizer.NAME);
final QueryComponent filter2 = Query.field("text").text().containsPrefix("th");
final Comparisons.Comparison comparison2 = new Comparisons.TextComparison(Comparisons.Type.TEXT_CONTAINS_PREFIX, Collections.singletonList("th"), null, DefaultTextTokenizer.NAME);
// Query for full records
RecordQuery query = RecordQuery.newBuilder().setRecordType(SIMPLE_DOC).setFilter(filter1).build();
// TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PHRASE civil blood makes civil hands unclean, null)
RecordQueryPlan plan = planner.plan(query);
assertThat(plan, textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison1)))));
assertEquals(814602491, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1101247748, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1215587201, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
List<Long> primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
assertEquals(Collections.singletonList(2L), primaryKeys);
query = RecordQuery.newBuilder().setRecordType(SIMPLE_DOC).setFilter(filter2).build();
// TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PREFIX [th], null) | UnorderedPrimaryKeyDistinct()
plan = planner.plan(query);
assertThat(plan, primaryKeyDistinct(textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison2))))));
assertEquals(1032989149, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1513880131, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1570861632, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
assertEquals(Arrays.asList(0L, 1L, 2L, 3L), primaryKeys);
// Query for just primary key
query = RecordQuery.newBuilder().setRecordType(SIMPLE_DOC).setRequiredResults(Collections.singletonList(field("doc_id"))).setFilter(filter1).build();
// Covering(TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PHRASE civil blood makes civil hands unclean, null) -> [doc_id: KEY[1]])
plan = planner.plan(query);
assertThat(plan, coveringIndexScan(textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison1))))));
assertEquals(814602491, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-786467136, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(1191665211, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
assertEquals(Collections.singletonList(2L), primaryKeys);
query = RecordQuery.newBuilder().setRecordType(SIMPLE_DOC).setRequiredResults(Collections.singletonList(field("doc_id"))).setFilter(filter2).build();
// Covering(TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PREFIX [th], null) -> [doc_id: KEY[1]]) | UnorderedPrimaryKeyDistinct()
plan = planner.plan(query);
assertThat(plan, primaryKeyDistinct(coveringIndexScan(textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison2)))))));
assertEquals(1032989149, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(893372281, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(836390780, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
assertEquals(Arrays.asList(0L, 1L, 2L, 3L), primaryKeys);
// Query for primary key but also have a filter on something outside the index
query = RecordQuery.newBuilder().setRecordType(SIMPLE_DOC).setRequiredResults(Collections.singletonList(field("doc_id"))).setFilter(Query.and(filter1, Query.field("group").equalsValue(0L))).build();
// Covering(TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PREFIX [th], null) -> [doc_id: KEY[1]]) | UnorderedPrimaryKeyDistinct()
plan = planner.plan(query);
assertThat(plan, filter(Query.field("group").equalsValue(0L), textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison1))))));
assertEquals(-1328921799, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(390154904, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-611539723, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
assertEquals(Collections.singletonList(2L), primaryKeys);
query = RecordQuery.newBuilder().setRecordType(SIMPLE_DOC).setRequiredResults(Collections.singletonList(field("doc_id"))).setFilter(Query.and(filter2, Query.field("group").equalsValue(0L))).build();
// TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PHRASE civil blood makes civil hands unclean, null) | group EQUALS 0
plan = planner.plan(query);
System.out.println(plan.planHash(PlanHashable.PlanHashKind.LEGACY));
System.out.println(plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
System.out.println(plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
assertThat(plan, filter(Query.field("group").equalsValue(0L), fetch(primaryKeyDistinct(coveringIndexScan(textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison2)))))))));
assertEquals(792432470, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-879354804, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-545069279, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
assertEquals(Arrays.asList(0L, 2L), primaryKeys);
// Query for the text field, which produces the first token that matches
// Arguably, this should produce an error, but that requires a more sophisticated
// check when trying to determine if the index covers the query
final Descriptors.FieldDescriptor docIdDescriptor = SimpleDocument.getDescriptor().findFieldByNumber(SimpleDocument.DOC_ID_FIELD_NUMBER);
final Descriptors.FieldDescriptor textDescriptor = SimpleDocument.getDescriptor().findFieldByNumber(SimpleDocument.TEXT_FIELD_NUMBER);
query = RecordQuery.newBuilder().setRecordType(SIMPLE_DOC).setRequiredResults(Collections.singletonList(field("text"))).setFilter(filter1).build();
// Fetch(Covering(TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PREFIX [th], null) -> [doc_id: KEY[1]]) | UnorderedPrimaryKeyDistinct()) | group EQUALS 0
plan = planner.plan(query);
assertThat(plan, textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison1)))));
assertEquals(814602491, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(1101247748, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1215587201, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
List<Tuple> idTextTuples = recordStore.executeQuery(plan).map(record -> {
final Object docId = record.getRecord().getField(docIdDescriptor);
final Object text = record.getRecord().getField(textDescriptor);
return Tuple.from(docId, text);
}).asList().get();
assertEquals(Collections.singletonList(Tuple.from(2L, TextSamples.ROMEO_AND_JULIET_PROLOGUE)), idTextTuples);
query = RecordQuery.newBuilder().setRecordType(SIMPLE_DOC).setRequiredResults(Collections.singletonList(field("text"))).setFilter(filter2).build();
// TextIndex(SimpleDocument$text null, TEXT_CONTAINS_PHRASE civil blood makes civil hands unclean, null)
plan = planner.plan(query);
assertThat(plan, fetch(primaryKeyDistinct(coveringIndexScan(textIndexScan(allOf(indexName(TextIndexTestUtils.SIMPLE_DEFAULT_NAME), textComparison(equalTo(comparison2))))))));
assertEquals(-1359010536, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1017914160, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1074895661, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
idTextTuples = recordStore.executeQuery(plan).map(record -> {
final Object docId = record.getRecord().getField(docIdDescriptor);
final Object text = record.getRecord().getField(textDescriptor);
return Tuple.from(docId, text);
}).asList().get();
assertEquals(Arrays.asList(Tuple.from(0L, TextSamples.ANGSTROM), Tuple.from(1L, TextSamples.AETHELRED), Tuple.from(2L, TextSamples.ROMEO_AND_JULIET_PROLOGUE), Tuple.from(3L, TextSamples.FRENCH)), idTextTuples);
commit(context);
}
}
use of com.apple.foundationdb.record.provider.foundationdb.indexes.TextIndexTestUtils.SIMPLE_DOC in project fdb-record-layer by FoundationDB.
the class TextIndexTest method saveSimpleWithAggressiveConflictRanges.
@Test
public void saveSimpleWithAggressiveConflictRanges() throws Exception {
// These two documents are from different languages and thus have no conflicts, so
// without the aggressive conflict ranges, they wouldn't conflict if not
// for the aggressive conflict ranges
final SimpleDocument shakespeareDocument = SimpleDocument.newBuilder().setDocId(1623L).setGroup(0).setText(TextSamples.ROMEO_AND_JULIET_PROLOGUE).build();
final SimpleDocument yiddishDocument = SimpleDocument.newBuilder().setDocId(1945L).setGroup(0).setText(TextSamples.YIDDISH).build();
final RecordMetaDataHook hook = metaDataBuilder -> {
final Index oldIndex = metaDataBuilder.getIndex(TextIndexTestUtils.SIMPLE_DEFAULT_NAME);
metaDataBuilder.removeIndex(TextIndexTestUtils.SIMPLE_DEFAULT_NAME);
final Index newIndex = new Index(TextIndexTestUtils.SIMPLE_DEFAULT_NAME + "-new", oldIndex.getRootExpression(), IndexTypes.TEXT, ImmutableMap.of(IndexOptions.TEXT_ADD_AGGRESSIVE_CONFLICT_RANGES_OPTION, "true"));
metaDataBuilder.addIndex(SIMPLE_DOC, newIndex);
};
saveTwoRecordsConcurrently(hook, shakespeareDocument, yiddishDocument, false);
}
Aggregations