diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2023-01-12 16:30:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-12 16:30:57 +0100 |
commit | 697182201491bf75fdd8e5a630208ae8b374b4fd (patch) | |
tree | 3d53e90b796b8823836349d8b8a5cc32d90375b7 /searchlib | |
parent | 8898b97886e8a812fd7e19ba77c0204f4970f20e (diff) | |
parent | ca18a63e3b492b218026ca012970d4bb7cecc992 (diff) |
Merge pull request #25541 from vespa-engine/geirst/expose-same-element-terms-to-ranking
Expose SameElement query terms to ranking.
Diffstat (limited to 'searchlib')
21 files changed, 110 insertions, 41 deletions
diff --git a/searchlib/src/tests/features/prod_features.cpp b/searchlib/src/tests/features/prod_features.cpp index 03563196379..81c46558381 100644 --- a/searchlib/src/tests/features/prod_features.cpp +++ b/searchlib/src/tests/features/prod_features.cpp @@ -1717,6 +1717,17 @@ Test::testMatches() EXPECT_TRUE(ft.execute(RankResult().addScore("matches(foo,2)", 0))); EXPECT_TRUE(ft.execute(RankResult().addScore("matches(foo,3)", 0))); } + { // Test executor for virtual fields + FtFeatureTest ft(_factory, StringList().add("matches(foo)")); + ft.getIndexEnv().getBuilder().addField(FieldType::VIRTUAL, CollectionType::ARRAY, "foo"); + ASSERT_TRUE(ft.getQueryEnv().getBuilder().add_virtual_node("foo") != nullptr); // query term 0 hits in foo + ASSERT_TRUE(ft.setup()); + + auto mdb = ft.createMatchDataBuilder(); + mdb->setWeight("foo", 0, 100); + mdb->apply(1); + EXPECT_TRUE(ft.execute(RankResult().addScore("matches(foo)", 1))); + } } bool diff --git a/searchlib/src/tests/query/customtypevisitor_test.cpp b/searchlib/src/tests/query/customtypevisitor_test.cpp index 86288fda498..3f68e423b08 100644 --- a/searchlib/src/tests/query/customtypevisitor_test.cpp +++ b/searchlib/src/tests/query/customtypevisitor_test.cpp @@ -27,7 +27,7 @@ struct MyNear : Near { MyNear() : Near(1) {} }; struct MyONear : ONear { MyONear() : ONear(1) {} }; struct MyOr : Or {}; struct MyPhrase : Phrase { MyPhrase() : Phrase("view", 0, Weight(42)) {} }; -struct MySameElement : SameElement { MySameElement() : SameElement("view") {} }; +struct MySameElement : SameElement { MySameElement() : SameElement("view", 0, Weight(42)) {} }; struct MyRank : Rank {}; struct MyNumberTerm : InitTerm<NumberTerm> {}; struct MyLocationTerm : InitTerm<LocationTerm> {}; diff --git a/searchlib/src/tests/query/query_visitor_test.cpp b/searchlib/src/tests/query/query_visitor_test.cpp index 8e8be997be0..48efb32afb3 100644 --- a/searchlib/src/tests/query/query_visitor_test.cpp +++ b/searchlib/src/tests/query/query_visitor_test.cpp @@ -68,7 +68,7 @@ TEST("requireThatAllNodesCanBeVisited") { checkVisit<ONear>(new SimpleONear(0)); checkVisit<Or>(new SimpleOr); checkVisit<Phrase>(new SimplePhrase("field", 0, Weight(42))); - checkVisit<SameElement>(new SimpleSameElement("field")); + checkVisit<SameElement>(new SimpleSameElement("field", 0, Weight(42))); checkVisit<WeightedSetTerm>(new SimpleWeightedSetTerm(0, "field", 0, Weight(42))); checkVisit<DotProduct>(new SimpleDotProduct(0, "field", 0, Weight(42))); checkVisit<WandTerm>(new SimpleWandTerm(0, "field", 0, Weight(42), 57, 67, 77.7)); diff --git a/searchlib/src/tests/query/querybuilder_test.cpp b/searchlib/src/tests/query/querybuilder_test.cpp index 32285918826..3922c581004 100644 --- a/searchlib/src/tests/query/querybuilder_test.cpp +++ b/searchlib/src/tests/query/querybuilder_test.cpp @@ -105,7 +105,7 @@ Node::UP createQueryTree() { n.addTerm(str[2], weight[2]); } builder.addRegExpTerm(str[5], view[5], id[5], weight[5]); - builder.addSameElement(3, view[4]); + builder.addSameElement(3, view[4], id[4], weight[4]); { builder.addStringTerm(str[4], view[4], id[4], weight[5]); builder.addStringTerm(str[5], view[5], id[5], weight[6]); @@ -381,7 +381,7 @@ struct MyONear : ONear { MyONear(size_t dist) : ONear(dist) {} }; struct MyWeakAnd : WeakAnd { MyWeakAnd(uint32_t minHits, const vespalib::string & v) : WeakAnd(minHits, v) {} }; struct MyOr : Or {}; struct MyPhrase : Phrase { MyPhrase(const string &f, int32_t i, Weight w) : Phrase(f, i, w) {}}; -struct MySameElement : SameElement { MySameElement(const string &f) : SameElement(f) {}}; +struct MySameElement : SameElement { MySameElement(const string &f, int32_t i, Weight w) : SameElement(f, i, w) {}}; struct MyWeightedSetTerm : WeightedSetTerm { MyWeightedSetTerm(uint32_t n, const string &f, int32_t i, Weight w) : WeightedSetTerm(n, f, i, w) {} diff --git a/searchlib/src/tests/query/streaming_query_test.cpp b/searchlib/src/tests/query/streaming_query_test.cpp index 4b5433dd370..f354f635def 100644 --- a/searchlib/src/tests/query/streaming_query_test.cpp +++ b/searchlib/src/tests/query/streaming_query_test.cpp @@ -734,7 +734,7 @@ namespace { } TEST("testSameElementEvaluate") { QueryBuilder<SimpleQueryNodeTypes> builder; - builder.addSameElement(3, "field"); + builder.addSameElement(3, "field", 0, Weight(0)); { builder.addStringTerm("a", "f1", 0, Weight(0)); builder.addStringTerm("b", "f2", 1, Weight(0)); diff --git a/searchlib/src/tests/query/templatetermvisitor_test.cpp b/searchlib/src/tests/query/templatetermvisitor_test.cpp index 7643139d5ad..15ce314b01f 100644 --- a/searchlib/src/tests/query/templatetermvisitor_test.cpp +++ b/searchlib/src/tests/query/templatetermvisitor_test.cpp @@ -71,12 +71,12 @@ void Test::requireThatAllTermsCanBeVisited() { EXPECT_TRUE(checkVisit<SimplePredicateQuery>()); EXPECT_TRUE(checkVisit<SimpleRegExpTerm>()); EXPECT_TRUE(checkVisit(new SimplePhrase("field", 0, Weight(0)))); + EXPECT_TRUE(checkVisit(new SimpleSameElement("foo", 0, Weight(0)))); EXPECT_TRUE(!checkVisit(new SimpleAnd)); EXPECT_TRUE(!checkVisit(new SimpleAndNot)); EXPECT_TRUE(!checkVisit(new SimpleEquiv(17, Weight(100)))); EXPECT_TRUE(!checkVisit(new SimpleNear(2))); EXPECT_TRUE(!checkVisit(new SimpleONear(2))); - EXPECT_TRUE(!checkVisit(new SimpleSameElement("foo"))); EXPECT_TRUE(!checkVisit(new SimpleOr)); EXPECT_TRUE(!checkVisit(new SimpleRank)); } @@ -84,4 +84,3 @@ void Test::requireThatAllTermsCanBeVisited() { } // namespace TEST_APPHOOK(Test); -#include <vespa/vespalib/testkit/testapp.h> diff --git a/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp b/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp index 83dc574c16c..6c344d787ab 100644 --- a/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp +++ b/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp @@ -306,8 +306,9 @@ struct ParallelWeakAndAdapter { // enable Make-ing same element struct SameElementAdapter { + FieldSpec field; SameElementBlueprint blueprint; - SameElementAdapter() : blueprint("foo", false) {} + SameElementAdapter() : field("foo", 5, 11), blueprint(field, false) {} void addChild(std::unique_ptr<Blueprint> child) { auto child_field = blueprint.getNextChildField("foo", 3); auto term = std::make_unique<LeafProxy>(child_field, std::move(child)); diff --git a/searchlib/src/tests/queryeval/same_element/same_element_test.cpp b/searchlib/src/tests/queryeval/same_element/same_element_test.cpp index 7c2b5d0b135..fba8d5d7899 100644 --- a/searchlib/src/tests/queryeval/same_element/same_element_test.cpp +++ b/searchlib/src/tests/queryeval/same_element/same_element_test.cpp @@ -22,8 +22,19 @@ void verify_elements(SameElementSearch &se, uint32_t docid, const std::initializ EXPECT_EQUAL(actual, expect); } +FieldSpec make_field_spec() { + // This field spec is aligned with the match data created below. + uint32_t field_id = 0; + TermFieldHandle handle = 0; + return {"foo", field_id, handle}; +} + +MatchData::UP make_match_data() { + return MatchData::makeTestInstance(1, 1); +} + std::unique_ptr<SameElementBlueprint> make_blueprint(const std::vector<FakeResult> &children, bool fake_attr = false) { - auto result = std::make_unique<SameElementBlueprint>("foo", false); + auto result = std::make_unique<SameElementBlueprint>(make_field_spec(), false); for (size_t i = 0; i < children.size(); ++i) { uint32_t field_id = i; vespalib::string field_name = vespalib::make_string("f%u", field_id); @@ -43,7 +54,7 @@ Blueprint::UP finalize(Blueprint::UP bp, bool strict) { } SimpleResult find_matches(const std::vector<FakeResult> &children) { - auto md = MatchData::makeTestInstance(0, 0); + auto md = make_match_data(); auto bp = finalize(make_blueprint(children), false); auto search = bp->createSearch(*md, false); return SimpleResult().search(*search, 1000); @@ -73,7 +84,7 @@ TEST("require that matching elements can be identified") { auto a = make_result({{5, {1,3,7,12}}, {10, {1,2,3}}}); auto b = make_result({{5, {3,5,7,10}}, {10, {4,5,6}}}); auto bp = finalize(make_blueprint({a,b}), false); - auto md = MatchData::makeTestInstance(0, 0); + auto md = make_match_data(); auto search = bp->createSearch(*md, false); search->initRange(1, 1000); SameElementSearch *se = dynamic_cast<SameElementSearch*>(search.get()); @@ -91,18 +102,24 @@ TEST("require that children must match within same element") { EXPECT_EQUAL(result, expect); } -TEST("require that strict iterator seeks to next hit") { - auto md = MatchData::makeTestInstance(0, 0); +TEST("require that strict iterator seeks to next hit and can unpack matching docid") { + auto md = make_match_data(); auto a = make_result({{5, {1,2}}, {7, {1,2}}, {8, {1,2}}, {9, {1,2}}}); auto b = make_result({{5, {3}}, {6, {1,2}}, {7, {2,4}}, {9, {1}}}); auto bp = finalize(make_blueprint({a,b}), true); auto search = bp->createSearch(*md, true); + auto* tfmd = md->resolveTermField(0); search->initRange(1, 1000); EXPECT_LESS(search->getDocId(), 1u); EXPECT_FALSE(search->seek(1)); EXPECT_EQUAL(search->getDocId(), 7u); + search->unpack(7); + EXPECT_EQUAL(tfmd->getDocId(), 7u); EXPECT_TRUE(search->seek(9)); EXPECT_EQUAL(search->getDocId(), 9u); + EXPECT_EQUAL(tfmd->getDocId(), 7u); + search->unpack(9); + EXPECT_EQUAL(tfmd->getDocId(), 9u); EXPECT_FALSE(search->seek(10)); EXPECT_TRUE(search->isAtEnd()); } @@ -129,7 +146,7 @@ TEST("require that attribute iterators are wrapped for element unpacking") { auto a = make_result({{5, {1,3,7}}}); auto b = make_result({{5, {3,5,10}}}); auto bp = finalize(make_blueprint({a,b}, true), true); - auto md = MatchData::makeTestInstance(0, 0); + auto md = make_match_data(); auto search = bp->createSearch(*md, false); SameElementSearch *se = dynamic_cast<SameElementSearch*>(search.get()); ASSERT_TRUE(se != nullptr); diff --git a/searchlib/src/vespa/searchlib/fef/parameterdescriptions.h b/searchlib/src/vespa/searchlib/fef/parameterdescriptions.h index ec39e7bdf09..e47ce0df7a5 100644 --- a/searchlib/src/vespa/searchlib/fef/parameterdescriptions.h +++ b/searchlib/src/vespa/searchlib/fef/parameterdescriptions.h @@ -68,7 +68,8 @@ private: return (normalTypesMask() | asMask(DataType::BOOLEANTREE) | asMask(DataType::TENSOR) | - asMask(DataType::REFERENCE)); + asMask(DataType::REFERENCE) | + asMask(DataType::COMBINED)); } ParameterDataTypeSet(uint32_t typeMask) : _typeMask(typeMask) diff --git a/searchlib/src/vespa/searchlib/fef/test/queryenvironmentbuilder.cpp b/searchlib/src/vespa/searchlib/fef/test/queryenvironmentbuilder.cpp index ec9875ad63f..da72374e7e3 100644 --- a/searchlib/src/vespa/searchlib/fef/test/queryenvironmentbuilder.cpp +++ b/searchlib/src/vespa/searchlib/fef/test/queryenvironmentbuilder.cpp @@ -52,10 +52,26 @@ QueryEnvironmentBuilder::addAttributeNode(const vespalib::string &attrName) if (info == nullptr || info->type() != FieldType::ATTRIBUTE) { return nullptr; } + return add_node(*info); +} + +SimpleTermData * +QueryEnvironmentBuilder::add_virtual_node(const vespalib::string &virtual_field) +{ + const auto *info = _queryEnv.getIndexEnv()->getFieldByName(virtual_field); + if (info == nullptr || info->type() != FieldType::VIRTUAL) { + return nullptr; + } + return add_node(*info); +} + +SimpleTermData * +QueryEnvironmentBuilder::add_node(const FieldInfo &info) +{ _queryEnv.getTerms().push_back(SimpleTermData()); SimpleTermData &td = _queryEnv.getTerms().back(); td.setWeight(search::query::Weight(100)); - SimpleTermFieldData &tfd = td.addField(info->id()); + SimpleTermFieldData &tfd = td.addField(info.id()); tfd.setHandle(_layout.allocTermField(tfd.getFieldId())); return &td; } diff --git a/searchlib/src/vespa/searchlib/fef/test/queryenvironmentbuilder.h b/searchlib/src/vespa/searchlib/fef/test/queryenvironmentbuilder.h index 19cf74673a2..d9378280f45 100644 --- a/searchlib/src/vespa/searchlib/fef/test/queryenvironmentbuilder.h +++ b/searchlib/src/vespa/searchlib/fef/test/queryenvironmentbuilder.h @@ -45,6 +45,11 @@ public: */ SimpleTermData *addAttributeNode(const vespalib::string & attrName); + /** + * Add a term node searching in the given virtual field. + */ + SimpleTermData *add_virtual_node(const vespalib::string &virtual_field); + /** Returns a reference to the query environment of this. */ QueryEnvironment &getQueryEnv() { return _queryEnv; } @@ -62,6 +67,7 @@ public: private: QueryEnvironmentBuilder(const QueryEnvironmentBuilder &); // hide QueryEnvironmentBuilder & operator=(const QueryEnvironmentBuilder &); // hide + SimpleTermData *add_node(const FieldInfo &info); private: QueryEnvironment &_queryEnv; diff --git a/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h b/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h index 98825fc5a32..30160c3d532 100644 --- a/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h +++ b/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h @@ -107,18 +107,17 @@ private: bool _expensive; }; -class SameElement : public QueryNodeMixin<SameElement, Intermediate> { +class SameElement : public QueryNodeMixin<SameElement, Intermediate>, public Term { public: - SameElement(const vespalib::string &view) : _view(view), _expensive(false) {} + SameElement(const vespalib::string &view, int32_t id, Weight weight) + : Term(view, id, weight), _expensive(false) {} virtual ~SameElement() = 0; - const vespalib::string & getView() const { return _view; } SameElement &set_expensive(bool value) { _expensive = value; return *this; } bool is_expensive() const { return _expensive; } private: - vespalib::string _view; bool _expensive; }; diff --git a/searchlib/src/vespa/searchlib/query/tree/querybuilder.h b/searchlib/src/vespa/searchlib/query/tree/querybuilder.h index 2273dadbfcf..979f48fec89 100644 --- a/searchlib/src/vespa/searchlib/query/tree/querybuilder.h +++ b/searchlib/src/vespa/searchlib/query/tree/querybuilder.h @@ -129,8 +129,8 @@ typename NodeTypes::Phrase *createPhrase(vespalib::stringref view, int32_t id, W return new typename NodeTypes::Phrase(view, id, weight); } template <class NodeTypes> -typename NodeTypes::SameElement *createSameElement(vespalib::stringref view) { - return new typename NodeTypes::SameElement(view); +typename NodeTypes::SameElement *createSameElement(vespalib::stringref view, int32_t id, Weight weight) { + return new typename NodeTypes::SameElement(view, id, weight); } template <class NodeTypes> typename NodeTypes::WeightedSetTerm *createWeightedSetTerm(uint32_t num_terms, vespalib::stringref view, int32_t id, Weight weight) { @@ -271,8 +271,8 @@ public: setWeightOverride(weight); return node; } - typename NodeTypes::SameElement &addSameElement(int child_count, stringref view) { - return addIntermediate(createSameElement<NodeTypes>(view), child_count); + typename NodeTypes::SameElement &addSameElement(int child_count, stringref view, int32_t id, Weight weight) { + return addIntermediate(createSameElement<NodeTypes>(view, id, weight), child_count); } typename NodeTypes::WeightedSetTerm &addWeightedSetTerm( int child_count, stringref view, int32_t id, Weight weight) { adjustWeight(weight); diff --git a/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h b/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h index 52cfbc5effb..612c3b68382 100644 --- a/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h +++ b/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h @@ -74,7 +74,8 @@ private: } void visit(SameElement &node) override { - _builder.addSameElement(node.getChildren().size(), node.getView()).set_expensive(node.is_expensive()); + _builder.addSameElement(node.getChildren().size(), node.getView(), + node.getId(), node.getWeight()).set_expensive(node.is_expensive()); visitNodes(node.getChildren()); } diff --git a/searchlib/src/vespa/searchlib/query/tree/simplequery.h b/searchlib/src/vespa/searchlib/query/tree/simplequery.h index 05e731c0c5c..31cd73d9f48 100644 --- a/searchlib/src/vespa/searchlib/query/tree/simplequery.h +++ b/searchlib/src/vespa/searchlib/query/tree/simplequery.h @@ -54,7 +54,8 @@ struct SimplePhrase : Phrase { }; struct SimpleSameElement : SameElement { - SimpleSameElement(vespalib::stringref view) : SameElement(view) {} + SimpleSameElement(vespalib::stringref view, int32_t id, Weight weight) + : SameElement(view, id, weight) {} ~SimpleSameElement() override; }; struct SimpleWeightedSetTerm : WeightedSetTerm { diff --git a/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h b/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h index 4103c3b1766..90bd87979c7 100644 --- a/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h +++ b/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h @@ -110,7 +110,9 @@ private: pureTermView = view; } else if (type == ParseItem::ITEM_SAME_ELEMENT) { vespalib::stringref view = queryStack.getIndexName(); - builder.addSameElement(arity, view); + int32_t id = queryStack.getUniqueId(); + Weight weight = queryStack.GetWeight(); + builder.addSameElement(arity, view, id, weight); pureTermView = view; } else if (type == ParseItem::ITEM_WEIGHTED_SET) { vespalib::stringref view = queryStack.getIndexName(); diff --git a/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h b/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h index a6eae257afd..cafb9a214e7 100644 --- a/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h +++ b/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h @@ -53,6 +53,11 @@ class TemplateTermVisitor : public CustomTypeTermVisitor<NodeTypes> { // term's children, unless this member function is overridden // to do so. void visit(typename NodeTypes::WandTerm &n) override { myVisit(n); } + + // SameElement have children. This visitor will not visit the + // term's children, unless this member function is overridden + // to do so. + void visit(typename NodeTypes::SameElement &n) override { myVisit(n); } }; } diff --git a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp index aeaa0f98c2f..3be28ab75de 100644 --- a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp @@ -13,12 +13,12 @@ namespace search::queryeval { -SameElementBlueprint::SameElementBlueprint(const vespalib::string &field_name_in, bool expensive) - : ComplexLeafBlueprint(FieldSpecBaseList()), +SameElementBlueprint::SameElementBlueprint(const FieldSpec &field, bool expensive) + : ComplexLeafBlueprint(field), _estimate(), _layout(), _terms(), - _field_name(field_name_in) + _field_name(field.getName()) { if (expensive) { set_cost_tier(State::COST_TIER_EXPENSIVE); @@ -64,7 +64,7 @@ SameElementBlueprint::fetchPostings(const ExecuteInfo &execInfo) } std::unique_ptr<SameElementSearch> -SameElementBlueprint::create_same_element_search(bool strict) const +SameElementBlueprint::create_same_element_search(search::fef::TermFieldMatchData& tfmd, bool strict) const { fef::MatchDataLayout my_layout = _layout; fef::MatchData::UP md = my_layout.createMatchData(); @@ -79,15 +79,14 @@ SameElementBlueprint::create_same_element_search(bool strict) const children[i] = std::make_unique<attribute::SearchContextElementIterator>(std::move(child), *context); } } - return std::make_unique<SameElementSearch>(std::move(md), std::move(children), strict); + return std::make_unique<SameElementSearch>(tfmd, std::move(md), std::move(children), strict); } SearchIterator::UP SameElementBlueprint::createLeafSearch(const search::fef::TermFieldMatchDataArray &tfmda, bool strict) const { - (void) tfmda; - assert(!tfmda.valid()); - return create_same_element_search(strict); + assert(tfmda.size() == 1); + return create_same_element_search(*tfmda[0], strict); } SearchIterator::UP diff --git a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h index 2d3cb5cca99..4fa42d87d0e 100644 --- a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h +++ b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h @@ -20,7 +20,7 @@ private: vespalib::string _field_name; public: - SameElementBlueprint(const vespalib::string &field_name_in, bool expensive); + SameElementBlueprint(const FieldSpec &field, bool expensive); SameElementBlueprint(const SameElementBlueprint &) = delete; SameElementBlueprint &operator=(const SameElementBlueprint &) = delete; ~SameElementBlueprint() override; @@ -37,7 +37,7 @@ public: void optimize_self() override; void fetchPostings(const ExecuteInfo &execInfo) override; - std::unique_ptr<SameElementSearch> create_same_element_search(bool strict) const; + std::unique_ptr<SameElementSearch> create_same_element_search(search::fef::TermFieldMatchData& tfmd, bool strict) const; SearchIteratorUP createLeafSearch(const search::fef::TermFieldMatchDataArray &tfmda, bool strict) const override; SearchIteratorUP createFilterSearch(bool strict, FilterConstraint constraint) const override; diff --git a/searchlib/src/vespa/searchlib/queryeval/same_element_search.cpp b/searchlib/src/vespa/searchlib/queryeval/same_element_search.cpp index dfa98b6b206..98c51d7f1ca 100644 --- a/searchlib/src/vespa/searchlib/queryeval/same_element_search.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/same_element_search.cpp @@ -39,13 +39,16 @@ SameElementSearch::check_element_match(uint32_t docid) return !_matchingElements.empty(); } -SameElementSearch::SameElementSearch(fef::MatchData::UP md, +SameElementSearch::SameElementSearch(fef::TermFieldMatchData &tfmd, + fef::MatchData::UP md, std::vector<ElementIterator::UP> children, bool strict) - : _md(std::move(md)), + : _tfmd(tfmd), + _md(std::move(md)), _children(std::move(children)), _strict(strict) { + _tfmd.reset(0); assert(!_children.empty()); } @@ -76,6 +79,12 @@ SameElementSearch::doSeek(uint32_t docid) { } void +SameElementSearch::doUnpack(uint32_t docid) +{ + _tfmd.resetOnlyDocId(docid); +} + +void SameElementSearch::visitMembers(vespalib::ObjectVisitor &visitor) const { SearchIterator::visitMembers(visitor); diff --git a/searchlib/src/vespa/searchlib/queryeval/same_element_search.h b/searchlib/src/vespa/searchlib/queryeval/same_element_search.h index b50a3ad8666..e1ec1869ac3 100644 --- a/searchlib/src/vespa/searchlib/queryeval/same_element_search.h +++ b/searchlib/src/vespa/searchlib/queryeval/same_element_search.h @@ -21,6 +21,7 @@ class SameElementSearch : public SearchIterator private: using It = fef::TermFieldMatchData::PositionsIterator; + fef::TermFieldMatchData &_tfmd; fef::MatchData::UP _md; std::vector<ElementIterator::UP> _children; std::vector<uint32_t> _matchingElements; @@ -31,12 +32,13 @@ private: bool check_element_match(uint32_t docid); public: - SameElementSearch(fef::MatchData::UP md, + SameElementSearch(fef::TermFieldMatchData &tfmd, + fef::MatchData::UP md, std::vector<ElementIterator::UP> children, bool strict); void initRange(uint32_t begin_id, uint32_t end_id) override; void doSeek(uint32_t docid) override; - void doUnpack(uint32_t) override {} + void doUnpack(uint32_t docid) override; void visitMembers(vespalib::ObjectVisitor &visitor) const override; const std::vector<ElementIterator::UP> &children() const { return _children; } |