aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2023-01-12 16:30:57 +0100
committerGitHub <noreply@github.com>2023-01-12 16:30:57 +0100
commit697182201491bf75fdd8e5a630208ae8b374b4fd (patch)
tree3d53e90b796b8823836349d8b8a5cc32d90375b7 /searchlib
parent8898b97886e8a812fd7e19ba77c0204f4970f20e (diff)
parentca18a63e3b492b218026ca012970d4bb7cecc992 (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')
-rw-r--r--searchlib/src/tests/features/prod_features.cpp11
-rw-r--r--searchlib/src/tests/query/customtypevisitor_test.cpp2
-rw-r--r--searchlib/src/tests/query/query_visitor_test.cpp2
-rw-r--r--searchlib/src/tests/query/querybuilder_test.cpp4
-rw-r--r--searchlib/src/tests/query/streaming_query_test.cpp2
-rw-r--r--searchlib/src/tests/query/templatetermvisitor_test.cpp3
-rw-r--r--searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp3
-rw-r--r--searchlib/src/tests/queryeval/same_element/same_element_test.cpp29
-rw-r--r--searchlib/src/vespa/searchlib/fef/parameterdescriptions.h3
-rw-r--r--searchlib/src/vespa/searchlib/fef/test/queryenvironmentbuilder.cpp18
-rw-r--r--searchlib/src/vespa/searchlib/fef/test/queryenvironmentbuilder.h6
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h7
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/querybuilder.h8
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/queryreplicator.h3
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/simplequery.h3
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h4
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h5
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp15
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h4
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/same_element_search.cpp13
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/same_element_search.h6
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; }