@@ -492,6 +492,115 @@ vector<SearchDocData> ShardDocIndex::SearchForAggregator(
492
492
return out;
493
493
}
494
494
495
+ join::Vector<join::OwnedEntry> ShardDocIndex::PreagregateDataForJoin (
496
+ const OpArgs& op_args, absl::Span<const std::string_view> join_fields,
497
+ search::SearchAlgorithm* search_algo) const {
498
+ auto search_results = search_algo->Search (&*indices_);
499
+
500
+ // First filter out sortable and non-sortable fields
501
+ // We will load them in different ways
502
+ const size_t fields_count = join_fields.size ();
503
+ std::vector<bool > is_sortable_field (fields_count);
504
+ std::vector<FieldReference> basic_fields;
505
+ basic_fields.reserve (fields_count);
506
+ for (size_t i = 0 ; i < fields_count; ++i) {
507
+ bool is_sortable = IsSortableField (join_fields[i], base_->schema );
508
+ is_sortable_field[i] = is_sortable;
509
+ if (!is_sortable) {
510
+ basic_fields.emplace_back (join_fields[i]);
511
+ }
512
+ }
513
+
514
+ join::Vector<join::OwnedEntry> result;
515
+ result.reserve (search_results.ids .size ());
516
+
517
+ const ShardId shard_id = op_args.shard ->shard_id ();
518
+ for (DocId doc : search_results.ids ) {
519
+ auto entry = LoadEntry (doc, op_args);
520
+ if (!entry)
521
+ continue ;
522
+
523
+ auto & [key, accessor] = *entry;
524
+
525
+ SearchDocData loaded_basic_fields = accessor->Serialize (base_->schema , basic_fields);
526
+
527
+ bool insert_key = true ;
528
+ join::Vector<join::OwnedJoinableValue> join_fields_values (fields_count);
529
+ for (size_t i = 0 ; i < fields_count; ++i) {
530
+ search::SortableValue value;
531
+ if (is_sortable_field[i]) {
532
+ value = indices_->GetSortIndexValue (doc, join_fields[i]);
533
+ } else {
534
+ value = loaded_basic_fields[join_fields[i]];
535
+ }
536
+
537
+ auto copy = [&](auto && v) {
538
+ using T = std::decay_t <decltype (v)>;
539
+ if constexpr (!std::is_same_v<T, std::monostate>) {
540
+ join_fields_values[i] = v;
541
+ } else {
542
+ // If the value is nil, we skip this key
543
+ insert_key = false ;
544
+ }
545
+ };
546
+
547
+ std::visit (std::move (copy), value);
548
+ }
549
+
550
+ if (insert_key) {
551
+ result.emplace_back (std::piecewise_construct, std::forward_as_tuple (shard_id, doc),
552
+ std::forward_as_tuple (std::make_move_iterator (join_fields_values.begin ()),
553
+ std::make_move_iterator (join_fields_values.end ())));
554
+ }
555
+ }
556
+
557
+ return result;
558
+ }
559
+
560
+ ShardDocIndex::FieldsValuesPerDocId ShardDocIndex::LoadKeysData (
561
+ const OpArgs& op_args, const absl::flat_hash_set<search::DocId>& doc_ids,
562
+ absl::Span<const std::string_view> fields_to_load) const {
563
+ const size_t fields_count = fields_to_load.size ();
564
+ std::vector<bool > is_sortable_field (fields_count);
565
+ std::vector<FieldReference> basic_fields;
566
+ basic_fields.reserve (fields_count);
567
+ for (size_t i = 0 ; i < fields_count; ++i) {
568
+ bool is_sortable = IsSortableField (fields_to_load[i], base_->schema );
569
+ is_sortable_field[i] = is_sortable;
570
+ if (!is_sortable) {
571
+ basic_fields.emplace_back (fields_to_load[i]);
572
+ }
573
+ }
574
+
575
+ FieldsValuesPerDocId result;
576
+ result.reserve (doc_ids.size ());
577
+
578
+ for (DocId doc : doc_ids) {
579
+ auto entry = LoadEntry (doc, op_args);
580
+ if (!entry)
581
+ continue ;
582
+
583
+ auto & [key, accessor] = *entry;
584
+
585
+ SearchDocData loaded_basic_fields = accessor->Serialize (base_->schema , basic_fields);
586
+
587
+ FieldsValues fields_values (fields_count);
588
+ for (size_t i = 0 ; i < fields_count; ++i) {
589
+ if (is_sortable_field[i]) {
590
+ fields_values[i] = indices_->GetSortIndexValue (doc, fields_to_load[i]);
591
+ } else {
592
+ fields_values[i] = loaded_basic_fields[fields_to_load[i]];
593
+ }
594
+ }
595
+
596
+ result.emplace (std::piecewise_construct, std::forward_as_tuple (doc),
597
+ std::forward_as_tuple (std::make_move_iterator (fields_values.begin ()),
598
+ std::make_move_iterator (fields_values.end ())));
599
+ }
600
+
601
+ return result;
602
+ }
603
+
495
604
DocIndexInfo ShardDocIndex::GetInfo () const {
496
605
return {*base_, key_index_.Size ()};
497
606
}
0 commit comments