diff options
author | Tor Egge <Tor.Egge@broadpark.no> | 2020-06-24 19:40:32 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@broadpark.no> | 2020-06-25 15:11:33 +0200 |
commit | 07344e04b5628b52da54aaeaed6a28fe979e83f1 (patch) | |
tree | d876a4c85ff43e66e6412c4bd965877193e24493 /searchlib | |
parent | 8109d90cf0249356c21a1f65d009381646e2540b (diff) |
Add filter iterators for weighted set blueprints.
Diffstat (limited to 'searchlib')
14 files changed, 404 insertions, 13 deletions
diff --git a/searchlib/CMakeLists.txt b/searchlib/CMakeLists.txt index f6e8d35459e..9b9f1a704cc 100644 --- a/searchlib/CMakeLists.txt +++ b/searchlib/CMakeLists.txt @@ -78,6 +78,7 @@ vespa_define_module( src/tests/attribute/changevector src/tests/attribute/compaction src/tests/attribute/document_weight_iterator + src/tests/attribute/document_weight_or_filter_search src/tests/attribute/enum_attribute_compaction src/tests/attribute/enum_comparator src/tests/attribute/enumeratedsave diff --git a/searchlib/src/tests/attribute/document_weight_or_filter_search/CMakeLists.txt b/searchlib/src/tests/attribute/document_weight_or_filter_search/CMakeLists.txt new file mode 100644 index 00000000000..660cfbaefff --- /dev/null +++ b/searchlib/src/tests/attribute/document_weight_or_filter_search/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +find_package(GTest REQUIRED) +vespa_add_executable(searchlib_document_weight_or_filter_search_test_app TEST + SOURCES + document_weight_or_filter_search_test.cpp + DEPENDS + searchlib + GTest::GTest +) +vespa_add_test(NAME searchlib_document_weight_or_filter_search_test_app COMMAND searchlib_document_weight_or_filter_search_test_app) diff --git a/searchlib/src/tests/attribute/document_weight_or_filter_search/document_weight_or_filter_search_test.cpp b/searchlib/src/tests/attribute/document_weight_or_filter_search/document_weight_or_filter_search_test.cpp new file mode 100644 index 00000000000..c8e799a8f10 --- /dev/null +++ b/searchlib/src/tests/attribute/document_weight_or_filter_search/document_weight_or_filter_search_test.cpp @@ -0,0 +1,203 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/vespalib/gtest/gtest.h> +#include <vespa/searchlib/attribute/i_document_weight_attribute.h> +#include <vespa/searchlib/attribute/document_weight_or_filter_search.h> +#include <vespa/searchlib/queryeval/searchiterator.h> +#include <vespa/searchlib/common/bitvector.h> + +using PostingList = search::attribute::PostingListTraits<int32_t>::PostingStoreBase; +using Iterator = search::attribute::PostingListTraits<int32_t>::const_iterator; +using KeyData = PostingList::KeyDataType; +using search::BitVector; +using search::attribute::DocumentWeightOrFilterSearch; +using search::queryeval::SearchIterator; +using vespalib::datastore::EntryRef; + +class DocumentWeightOrFilterSearchTest : public ::testing::Test { + PostingList _postings; + vespalib::GenerationHandler _gens; + std::vector<EntryRef> _trees; + uint32_t _range_start; + uint32_t _range_end; +protected: + DocumentWeightOrFilterSearchTest(); + ~DocumentWeightOrFilterSearchTest(); + void inc_generation(); + size_t num_trees() const { return _trees.size(); } + Iterator get_tree(size_t idx) const { + if (idx < _trees.size()) { + return _postings.beginFrozen(_trees[idx]); + } else { + return Iterator(); + } + } + void ensure_tree(size_t idx) { + if (idx <= _trees.size()) { + _trees.resize(idx + 1); + } + } + void add_tree(size_t idx, std::vector<uint32_t> keys) { + ensure_tree(idx); + std::vector<KeyData> adds; + std::vector<uint32_t> removes; + adds.reserve(keys.size()); + for (auto& key : keys) { + adds.emplace_back(KeyData(key, 1)); + } + _postings.apply(_trees[idx], &*adds.begin(), &*adds.end(), &*removes.begin(), &*removes.end()); + } + + std::unique_ptr<SearchIterator> make_iterator() const { + std::vector<Iterator> iterators; + for (size_t i = 0; i < num_trees(); ++i) { + iterators.emplace_back(get_tree(i)); + } + auto result = DocumentWeightOrFilterSearch::create(std::move(iterators)); + result->initRange(_range_start, _range_end); + return result; + }; + + std::vector<uint32_t> eval_daat(SearchIterator &iterator) { + std::vector<uint32_t> result; + uint32_t doc_id = _range_start; + while (doc_id < _range_end) { + if (iterator.seek(doc_id)) { + result.emplace_back(doc_id); + ++doc_id; + } else { + doc_id = std::max(doc_id + 1, iterator.getDocId()); + } + } + return result; + } + + std::vector<uint32_t> frombv(const BitVector &bv) { + std::vector<uint32_t> result; + uint32_t doc_id = _range_start; + doc_id = bv.getNextTrueBit(doc_id); + while (doc_id < _range_end) { + result.emplace_back(doc_id); + ++doc_id; + doc_id = bv.getNextTrueBit(doc_id); + } + return result; + } + + std::unique_ptr<BitVector> tobv(std::vector<uint32_t> values) { + auto bv = BitVector::create(_range_start, _range_end); + for (auto value : values) { + bv->setBit(value); + } + bv->invalidateCachedCount(); + return bv; + } + + void expect_result(std::vector<uint32_t> exp, std::vector<uint32_t> act) + { + EXPECT_EQ(exp, act); + } + + void make_sample_data() { + add_tree(0, { 10, 11 }); + add_tree(1, { 14, 17, 20 }); + add_tree(2, { 3 }); + add_tree(3, { 17 }); + } + + uint32_t get_range_start() const { return _range_start; } + void set_range(uint32_t start, uint32_t end) { + _range_start = start; + _range_end = end; + } +}; + +DocumentWeightOrFilterSearchTest::DocumentWeightOrFilterSearchTest() + : _postings(true), + _gens(), + _range_start(1), + _range_end(10000) +{ +} + +DocumentWeightOrFilterSearchTest::~DocumentWeightOrFilterSearchTest() +{ + for (auto& tree : _trees) { + _postings.clear(tree); + } + _postings.clearBuilder(); + _postings.clearHoldLists(); + inc_generation(); +} + +void +DocumentWeightOrFilterSearchTest::inc_generation() +{ + _postings.freeze(); + _postings.transferHoldLists(_gens.getCurrentGeneration()); + _gens.incGeneration(); + _gens.updateFirstUsedGeneration(); + _postings.trimHoldLists(_gens.getFirstUsedGeneration()); +} + +TEST_F(DocumentWeightOrFilterSearchTest, daat_or) +{ + make_sample_data(); + expect_result(eval_daat(*make_iterator()), { 3, 10, 11, 14, 17, 20 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_get_hits) +{ + make_sample_data(); + expect_result(frombv(*make_iterator()->get_hits(get_range_start())), { 3, 10, 11, 14, 17, 20 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_or_hits_into) +{ + make_sample_data(); + auto bv = tobv({13, 14}); + make_iterator()->or_hits_into(*bv, get_range_start()); + expect_result(frombv(*bv), { 3, 10, 11, 13, 14, 17, 20 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_and_hits_into) +{ + make_sample_data(); + auto bv = tobv({13, 14}); + make_iterator()->and_hits_into(*bv, get_range_start()); + expect_result(frombv(*bv), { 14 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, daat_or_ranged) +{ + make_sample_data(); + set_range(4, 15); + expect_result(eval_daat(*make_iterator()), {10, 11, 14 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_get_hits_ranged) +{ + make_sample_data(); + set_range(4, 15); + expect_result(frombv(*make_iterator()->get_hits(get_range_start())), { 10, 11, 14 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_or_hits_into_ranged) +{ + make_sample_data(); + set_range(4, 15); + auto bv = tobv({13, 14}); + make_iterator()->or_hits_into(*bv, get_range_start()); + expect_result(frombv(*bv), { 10, 11, 13, 14 }); +} + +TEST_F(DocumentWeightOrFilterSearchTest, taat_and_hits_into_ranged) +{ + make_sample_data(); + set_range(4, 15); + auto bv = tobv({13, 14}); + make_iterator()->and_hits_into(*bv, get_range_start()); + expect_result(frombv(*bv), { 14 }); +} + +GTEST_MAIN_RUN_ALL_TESTS() diff --git a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt index 6ab70e11fc0..bf56b476cc9 100644 --- a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt @@ -34,6 +34,7 @@ vespa_add_library(searchlib_attribute OBJECT defines.cpp diversity.cpp dociditerator.cpp + document_weight_or_filter_search.cpp searchcontextelementiterator.cpp enumattribute.cpp enumattributesaver.cpp diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp index 84bed6bb5e9..c4467df5a1c 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp @@ -6,6 +6,7 @@ #include "iterator_pack.h" #include "predicate_attribute.h" #include "attribute_blueprint_params.h" +#include "document_weight_or_filter_search.h" #include <vespa/eval/eval/value.h> #include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/searchlib/common/location.h> @@ -342,8 +343,22 @@ public: } return SearchType::create(*tfmda[0], _weights, std::move(iterators)); } + + std::unique_ptr<SearchIterator> createFilterSearch(bool strict, FilterConstraint constraint) const override; }; +template <typename SearchType> +std::unique_ptr<SearchIterator> +DirectWeightedSetBlueprint<SearchType>::createFilterSearch(bool, FilterConstraint) const +{ + std::vector<DocumentWeightIterator> iterators; + iterators.reserve(_terms.size()); + for (const IDocumentWeightAttribute::LookupResult &r : _terms) { + _attr.create(r.posting_idx, iterators); + } + return attribute::DocumentWeightOrFilterSearch::create(std::move(iterators)); +} + //----------------------------------------------------------------------------- class DirectWandBlueprint : public queryeval::ComplexLeafBlueprint diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp index 121cb736471..0959476158f 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp @@ -9,6 +9,8 @@ #include <vespa/vespalib/objects/visit.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/stllike/hash_map.hpp> +#include <vespa/searchlib/queryeval/filter_wrapper.h> +#include <vespa/searchlib/queryeval/orsearch.h> namespace search { @@ -182,6 +184,21 @@ AttributeWeightedSetBlueprint::createLeafSearch(const fef::TermFieldMatchDataArr } } +queryeval::SearchIterator::UP +AttributeWeightedSetBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const +{ + (void) constraint; + std::vector<std::unique_ptr<queryeval::SearchIterator>> children; + children.reserve(_contexts.size()); + for (auto& context : _contexts) { + auto wrapper = std::make_unique<search::queryeval::FilterWrapper>(1); + wrapper->wrap(context->createIterator(wrapper->tfmda()[0], strict)); + children.emplace_back(std::move(wrapper)); + } + search::queryeval::UnpackInfo unpack_info; + return search::queryeval::OrSearch::create(std::move(children), strict, unpack_info); +} + void AttributeWeightedSetBlueprint::fetchPostings(const queryeval::ExecuteInfo &execInfo) { diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.h b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.h index 6af3405c91d..7ab11aace81 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.h +++ b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.h @@ -29,6 +29,7 @@ public: ~AttributeWeightedSetBlueprint(); void addToken(std::unique_ptr<ISearchContext> context, int32_t weight); queryeval::SearchIterator::UP createLeafSearch(const fef::TermFieldMatchDataArray &tfmda, bool strict) const override; + queryeval::SearchIterator::UP createFilterSearch(bool strict, FilterConstraint constraint) const override; void fetchPostings(const queryeval::ExecuteInfo &execInfo) override; void visitMembers(vespalib::ObjectVisitor &visitor) const override; }; diff --git a/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp new file mode 100644 index 00000000000..9a181c37250 --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp @@ -0,0 +1,80 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "document_weight_or_filter_search.h" +#include "iterator_pack.h" +#include <vespa/searchlib/common/bitvector.h> +#include <vespa/searchlib/queryeval/emptysearch.h> + +namespace search::attribute { + +class DocumentWeightOrFilterSearchImpl : public DocumentWeightOrFilterSearch +{ + AttributeIteratorPack _children; +public: + DocumentWeightOrFilterSearchImpl(AttributeIteratorPack&& children); + ~DocumentWeightOrFilterSearchImpl(); + + void doSeek(uint32_t docId) override; + + void doUnpack(uint32_t) override; + + void initRange(uint32_t begin, uint32_t end) override { + SearchIterator::initRange(begin, end); + _children.initRange(begin, end); + } + + void or_hits_into(BitVector &result, uint32_t begin_id) override { + return _children.or_hits_into(result, begin_id); + } + + void and_hits_into(BitVector &result, uint32_t begin_id) override { + return result.andWith(*get_hits(begin_id)); + } + + std::unique_ptr<BitVector> get_hits(uint32_t begin_id) override { + return _children.get_hits(begin_id, getEndId()); + } + + Trinary is_strict() const override { return Trinary::True; } +}; + +DocumentWeightOrFilterSearchImpl::DocumentWeightOrFilterSearchImpl(AttributeIteratorPack&& children) + : DocumentWeightOrFilterSearch(), + _children(std::move(children)) +{ +} + +DocumentWeightOrFilterSearchImpl::~DocumentWeightOrFilterSearchImpl() = default; + +void +DocumentWeightOrFilterSearchImpl::doSeek(uint32_t docId) +{ + if (_children.get_docid(0) < docId) { + _children.seek(0, docId); + } + uint32_t min_doc_id = _children.get_docid(0); + for (unsigned int i = 1; min_doc_id > docId && i < _children.size(); ++i) { + if (_children.get_docid(i) < docId) { + _children.seek(i, docId); + } + min_doc_id = std::min(min_doc_id, _children.get_docid(i)); + } + setDocId(min_doc_id); +} + +void +DocumentWeightOrFilterSearchImpl::doUnpack(uint32_t) +{ +} + +std::unique_ptr<search::queryeval::SearchIterator> +DocumentWeightOrFilterSearch::create(std::vector<DocumentWeightIterator>&& children) +{ + if (children.empty()) { + return std::make_unique<queryeval::EmptySearch>(); + } else { + return std::make_unique<DocumentWeightOrFilterSearchImpl>(AttributeIteratorPack(std::move(children))); + } +} + +} diff --git a/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h new file mode 100644 index 00000000000..d9721871b81 --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h @@ -0,0 +1,23 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "i_document_weight_attribute.h" +#include <vespa/searchlib/queryeval/searchiterator.h> + +namespace search::attribute { + +/** + * Filter iterator on top of document weight iterators with OR semantics used during + * calculation of global filter for weighted set terms, wand terms and dot product terms. + */ +class DocumentWeightOrFilterSearch : public search::queryeval::SearchIterator +{ +protected: + DocumentWeightOrFilterSearch() + : search::queryeval::SearchIterator() + { + } +public: + static std::unique_ptr<search::queryeval::SearchIterator> create(std::vector<DocumentWeightIterator>&& children); +}; + +} diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp index 1a7a0c5eba2..0b4b5b29a8c 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp @@ -6,6 +6,8 @@ #include "emptysearch.h" #include "full_search.h" #include "field_spec.hpp" +#include "andsearch.h" +#include "orsearch.h" #include <vespa/searchlib/fef/termfieldmatchdataarray.h> #include <vespa/vespalib/objects/visit.hpp> #include <vespa/vespalib/objects/objectdumper.h> @@ -132,6 +134,38 @@ Blueprint::createFilterSearch(bool /*strict*/, FilterConstraint constraint) cons } } +namespace { + +template <typename Op> +std::unique_ptr<SearchIterator> +create_op_filter(const std::vector<Blueprint *>& children, bool strict, Blueprint::FilterConstraint constraint) +{ + MultiSearch::Children sub_searches; + sub_searches.reserve(children.size()); + for (size_t i = 0; i < children.size(); ++i) { + bool child_strict = strict && (std::is_same_v<Op,AndSearch> ? (i == 0) : true); + auto search = children[i]->createFilterSearch(child_strict, constraint); + sub_searches.push_back(std::move(search)); + } + UnpackInfo unpack_info; + auto search = Op::create(std::move(sub_searches), strict, unpack_info); + return search; +} + +} + +std::unique_ptr<SearchIterator> +Blueprint::create_and_filter(const std::vector<Blueprint *>& children, bool strict, Blueprint::FilterConstraint constraint) +{ + return create_op_filter<AndSearch>(children, strict, constraint); +} + +std::unique_ptr<SearchIterator> +Blueprint::create_or_filter(const std::vector<Blueprint *>& children, bool strict, Blueprint::FilterConstraint constraint) +{ + return create_op_filter<OrSearch>(children, strict, constraint); +} + vespalib::string Blueprint::asString() const { diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.h b/searchlib/src/vespa/searchlib/queryeval/blueprint.h index ef15736073e..1ee58f8b97d 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.h @@ -208,6 +208,9 @@ public: virtual SearchIteratorUP createSearch(fef::MatchData &md, bool strict) const = 0; virtual SearchIteratorUP createFilterSearch(bool strict, FilterConstraint constraint) const; + static std::unique_ptr<SearchIterator> create_and_filter(const std::vector<Blueprint *>& children, bool strict, FilterConstraint constraint); + static std::unique_ptr<SearchIterator> create_or_filter(const std::vector<Blueprint *>& children, bool strict, FilterConstraint constraint); + // for debug dumping vespalib::string asString() const; vespalib::slime::Cursor & asSlime(const vespalib::slime::Inserter & cursor) const; @@ -274,6 +277,8 @@ protected: bool should_do_termwise_eval(const UnpackInfo &unpack, double match_limit) const; + const Children& get_children() const { return _children; } + public: typedef std::vector<size_t> IndexList; IntermediateBlueprint(); diff --git a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp index 3d3a703cd7b..aa65342c114 100644 --- a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp @@ -84,18 +84,11 @@ need_normal_features_for_children(const IntermediateBlueprint &blueprint, fef::M /** utility for operators that degrade to AND when creating filter */ SearchIterator::UP createAndFilter(const IntermediateBlueprint &self, + const std::vector<Blueprint *>& children, bool strict, Blueprint::FilterConstraint constraint) { - MultiSearch::Children sub_searches; - sub_searches.reserve(self.childCnt()); - for (size_t i = 0; i < self.childCnt(); ++i) { - bool child_strict = strict && (i == 0); - auto search = self.getChild(i).createFilterSearch(child_strict, constraint); - sub_searches.push_back(std::move(search)); - } - UnpackInfo unpack_info; - auto search = AndSearch::create(std::move(sub_searches), strict, unpack_info); - search->estimate(self.getState().estimate().estHits); + auto search = Blueprint::create_and_filter(children, strict, constraint); + static_cast<AndSearch &>(*search).estimate(self.getState().estimate().estHits); return search; } @@ -292,7 +285,7 @@ AndBlueprint::createIntermediateSearch(MultiSearch::Children sub_searches, SearchIterator::UP AndBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const { - return createAndFilter(*this, strict, constraint); + return createAndFilter(*this, get_children(), strict, constraint); } double @@ -492,7 +485,7 @@ SearchIterator::UP NearBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const { if (constraint == Blueprint::FilterConstraint::UPPER_BOUND) { - return createAndFilter(*this, strict, constraint); + return createAndFilter(*this, get_children(), strict, constraint); } else { return std::make_unique<EmptySearch>(); } @@ -552,7 +545,7 @@ SearchIterator::UP ONearBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const { if (constraint == Blueprint::FilterConstraint::UPPER_BOUND) { - return createAndFilter(*this, strict, constraint); + return createAndFilter(*this, get_children(), strict, constraint); } else { return std::make_unique<EmptySearch>(); } diff --git a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp index cea35d976f0..3cfa928da87 100644 --- a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp @@ -2,6 +2,7 @@ #include "weighted_set_term_blueprint.h" #include "weighted_set_term_search.h" +#include "orsearch.h" #include <vespa/vespalib/objects/visit.hpp> namespace search::queryeval { @@ -56,6 +57,12 @@ WeightedSetTermBlueprint::createLeafSearch(const fef::TermFieldMatchDataArray &t return SearchIterator::UP(WeightedSetTermSearch::create(children, *tfmda[0], _weights, std::move(md))); } +SearchIterator::UP +WeightedSetTermBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const +{ + return create_or_filter(_terms, strict, constraint); +} + void WeightedSetTermBlueprint::fetchPostings(const ExecuteInfo &execInfo) { diff --git a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h index 8ae42607a9d..864e3e7fc7f 100644 --- a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h @@ -34,6 +34,7 @@ public: void addTerm(Blueprint::UP term, int32_t weight); SearchIteratorUP createLeafSearch(const fef::TermFieldMatchDataArray &tfmda, bool strict) const override; + SearchIteratorUP createFilterSearch(bool strict, FilterConstraint constraint) const override; void visitMembers(vespalib::ObjectVisitor &visitor) const override; private: |