21
21
#include " core/search/indices.h"
22
22
#include " core/search/query_driver.h"
23
23
#include " core/search/sort_indices.h"
24
+ #include " core/search/tag_types.h"
24
25
#include " core/search/vector_utils.h"
25
26
26
27
using namespace std ;
@@ -268,28 +269,14 @@ struct BasicSearch {
268
269
return out;
269
270
}
270
271
271
- template <typename C>
272
- IndexResult CollectPrefixMatches (BaseStringIndex<C>* index, std::string_view prefix ) {
272
+ template <typename C, typename F >
273
+ IndexResult CollectMatches (BaseStringIndex<C>* index, std::string_view word, F&& f ) {
273
274
IndexResult result{};
274
- index-> MatchingPrefix (
275
- prefix, [&result, this ](const auto * c) { Merge (IndexResult{c}, &result, LogicOp::OR); });
275
+ invoke (f, *index, word,
276
+ [&result, this ](const auto * c) { Merge (IndexResult{c}, &result, LogicOp::OR); });
276
277
return result;
277
278
}
278
279
279
- template <typename C>
280
- IndexResult CollectSuffixMatches (BaseStringIndex<C>* index, std::string_view suffix) {
281
- // TODO: Implement full text search for suffix
282
- error_ = " Not implemented" ;
283
- return IndexResult{};
284
- }
285
-
286
- template <typename C>
287
- IndexResult CollectInfixMatches (BaseStringIndex<C>* index, std::string_view infix) {
288
- // TODO: Implement full text search for infix
289
- error_ = " Not implemented" ;
290
- return IndexResult{};
291
- }
292
-
293
280
IndexResult Search (monostate, string_view) {
294
281
return IndexResult{};
295
282
}
@@ -299,32 +286,6 @@ struct BasicSearch {
299
286
return {&indices_->GetAllDocs ()};
300
287
}
301
288
302
- // "term": access field's text index or unify results from all text indices if no field is set
303
- IndexResult Search (const AstTermNode& node, string_view active_field) {
304
- std::string term = node.affix ;
305
- bool strip_whitespace = true ;
306
-
307
- if (auto synonyms = indices_->GetSynonyms (); synonyms) {
308
- if (auto group_id = synonyms->GetGroupToken (term); group_id) {
309
- term = *group_id;
310
- strip_whitespace = false ;
311
- }
312
- }
313
-
314
- if (!active_field.empty ()) {
315
- if (auto * index = GetIndex<TextIndex>(active_field); index)
316
- return index->Matching (term, strip_whitespace);
317
- return IndexResult{};
318
- }
319
-
320
- vector<TextIndex*> selected_indices = indices_->GetAllTextIndices ();
321
- auto mapping = [&term, strip_whitespace](TextIndex* index) {
322
- return index->Matching (term, strip_whitespace);
323
- };
324
-
325
- return UnifyResults (GetSubResults (selected_indices, mapping), LogicOp::OR);
326
- }
327
-
328
289
IndexResult Search (const AstStarFieldNode& node, string_view active_field) {
329
290
// Try to get a sort index first, as `@field:*` might imply wanting sortable behavior
330
291
BaseSortIndex* sort_index = indices_->GetSortIndex (active_field);
@@ -337,7 +298,7 @@ struct BasicSearch {
337
298
return base_index ? IndexResult{base_index->GetAllDocsWithNonNullValues ()} : IndexResult{};
338
299
}
339
300
340
- IndexResult Search (const AstPrefixNode & node, string_view active_field) {
301
+ template <TagType T> IndexResult Search (const AstAffixNode<T> & node, string_view active_field) {
341
302
vector<TextIndex*> indices;
342
303
if (!active_field.empty ()) {
343
304
if (auto * index = GetIndex<TextIndex>(active_field); index)
@@ -349,21 +310,42 @@ struct BasicSearch {
349
310
}
350
311
351
312
auto mapping = [&node, this ](TextIndex* index) {
352
- return CollectPrefixMatches (index, node.affix );
313
+ if constexpr (T == TagType::PREFIX)
314
+ return CollectMatches (index, node.affix , &TextIndex::MatchPrefix);
315
+ else if constexpr (T == TagType::SUFFIX)
316
+ return CollectMatches (index, node.affix , &TextIndex::MatchSuffix);
317
+ else if constexpr (T == TagType::INFIX)
318
+ return CollectMatches (index, node.affix , &TextIndex::MatchInfix);
319
+ else
320
+ return vector<DocId>{};
353
321
};
354
322
return UnifyResults (GetSubResults (indices, mapping), LogicOp::OR);
355
323
}
356
324
357
- IndexResult Search (const AstSuffixNode& node, string_view active_field) {
358
- // TODO: Implement full text search for suffix
359
- error_ = " Not implemented" ;
360
- return IndexResult{};
361
- }
325
+ // "term": access field's text index or unify results from all text indices if no field is set
326
+ IndexResult Search (const AstAffixNode<TagType::REGULAR> node, string_view active_field) {
327
+ std::string term = node.affix ;
328
+ bool strip_whitespace = true ;
362
329
363
- IndexResult Search (const AstInfixNode& node, string_view active_field) {
364
- // TODO: Implement full text search for infix
365
- error_ = " Not implemented" ;
366
- return IndexResult{};
330
+ if (auto synonyms = indices_->GetSynonyms (); synonyms) {
331
+ if (auto group_id = synonyms->GetGroupToken (term); group_id) {
332
+ term = *group_id;
333
+ strip_whitespace = false ;
334
+ }
335
+ }
336
+
337
+ if (!active_field.empty ()) {
338
+ if (auto * index = GetIndex<TextIndex>(active_field); index)
339
+ return index->Matching (term, strip_whitespace);
340
+ return IndexResult{};
341
+ }
342
+
343
+ vector<TextIndex*> selected_indices = indices_->GetAllTextIndices ();
344
+ auto mapping = [&term, strip_whitespace](TextIndex* index) {
345
+ return index->Matching (term, strip_whitespace);
346
+ };
347
+
348
+ return UnifyResults (GetSubResults (selected_indices, mapping), LogicOp::OR);
367
349
}
368
350
369
351
// [range]: access field's numeric index
@@ -411,13 +393,13 @@ struct BasicSearch {
411
393
return tag_index->Matching (term.affix );
412
394
},
413
395
[tag_index, this ](const AstPrefixNode& prefix) {
414
- return CollectPrefixMatches (tag_index, prefix.affix );
396
+ return CollectMatches (tag_index, prefix.affix , &TagIndex::MatchPrefix );
415
397
},
416
398
[tag_index, this ](const AstSuffixNode& suffix) {
417
- return CollectSuffixMatches (tag_index, suffix.affix );
399
+ return CollectMatches (tag_index, suffix.affix , &TagIndex::MatchSuffix );
418
400
},
419
401
[tag_index, this ](const AstInfixNode& infix) {
420
- return CollectInfixMatches (tag_index, infix.affix );
402
+ return CollectMatches (tag_index, infix.affix , &TagIndex::MatchInfix );
421
403
}};
422
404
auto mapping = [ov](const auto & tag) { return visit (ov, tag); };
423
405
return UnifyResults (GetSubResults (node.tags , mapping), LogicOp::OR);
@@ -570,9 +552,12 @@ void FieldIndices::CreateIndices(PMR_NS::memory_resource* mr) {
570
552
continue ;
571
553
572
554
switch (field_info.type ) {
573
- case SchemaField::TEXT:
574
- indices_[field_ident] = make_unique<TextIndex>(mr, &options_.stopwords , synonyms_);
555
+ case SchemaField::TEXT: {
556
+ const auto & tparams = std::get<SchemaField::TextParams>(field_info.special_params );
557
+ indices_[field_ident] =
558
+ make_unique<TextIndex>(mr, &options_.stopwords , synonyms_, tparams.with_suffixtrie );
575
559
break ;
560
+ }
576
561
case SchemaField::NUMERIC:
577
562
indices_[field_ident] = make_unique<NumericIndex>(mr);
578
563
break ;
0 commit comments