aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeir Storli <geirst@vespa.ai>2024-03-18 17:48:12 +0100
committerGitHub <noreply@github.com>2024-03-18 17:48:12 +0100
commitf30d81b16dd11fd68e1be04ab1685df26193735e (patch)
treecff1ed6fdd8e3a4080ce6edf096443846a07ab88
parentdd8ebed8c817e3ce39676cc41008dbe6131c29df (diff)
parentb700eeb73d8de490cdafbc3d004ed091e71e3c9e (diff)
Merge pull request #30670 from vespa-engine/toregge/change-parent-class-of-search-streaming-same-element-query-nodev8.321.19
Change parent class of search::streaming::SameElementQueryNode from
-rw-r--r--searchlib/src/tests/query/streaming/same_element_query_node_test.cpp45
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/equiv_query_node.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/equiv_query_node.h2
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/multi_term.cpp18
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/multi_term.h7
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/query.cpp1
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/querynode.cpp32
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/querynode.h1
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/queryterm.cpp12
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/queryterm.h2
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp51
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.h11
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp4
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/rankprocessor.h4
-rw-r--r--streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.cpp7
-rw-r--r--streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp6
16 files changed, 153 insertions, 56 deletions
diff --git a/searchlib/src/tests/query/streaming/same_element_query_node_test.cpp b/searchlib/src/tests/query/streaming/same_element_query_node_test.cpp
index ece6dc551b2..db1e5a1ef5d 100644
--- a/searchlib/src/tests/query/streaming/same_element_query_node_test.cpp
+++ b/searchlib/src/tests/query/streaming/same_element_query_node_test.cpp
@@ -1,12 +1,20 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/searchlib/query/streaming/same_element_query_node.h>
+#include <vespa/searchlib/fef/matchdata.h>
+#include <vespa/searchlib/fef/simpletermdata.h>
+#include <vespa/searchlib/fef/test/indexenvironment.h>
+#include <vespa/searchlib/query/streaming/query.h>
#include <vespa/searchlib/query/streaming/queryterm.h>
#include <vespa/searchlib/query/tree/querybuilder.h>
#include <vespa/searchlib/query/tree/simplequery.h>
#include <vespa/searchlib/query/tree/stackdumpcreator.h>
#include <vespa/vespalib/gtest/gtest.h>
+using search::fef::MatchData;
+using search::fef::SimpleTermData;
+using search::fef::TermFieldHandle;
+using search::fef::test::IndexEnvironment;
using search::query::QueryBuilder;
using search::query::Node;
using search::query::SimpleQueryNodeTypes;
@@ -44,11 +52,11 @@ TEST(SameElementQueryNodeTest, a_unhandled_sameElement_stack)
const QueryNode & root = q.getRoot();
auto sameElement = dynamic_cast<const SameElementQueryNode *>(&root);
EXPECT_TRUE(sameElement != nullptr);
- EXPECT_EQ(2u, sameElement->size());
+ EXPECT_EQ(2u, sameElement->get_terms().size());
EXPECT_EQ("xyz_abcdefghij_xyzxyzx", sameElement->getIndex());
- auto term0 = dynamic_cast<const QueryTerm *>((*sameElement)[0].get());
+ auto term0 = sameElement->get_terms()[0].get();
EXPECT_TRUE(term0 != nullptr);
- auto term1 = dynamic_cast<const QueryTerm *>((*sameElement)[1].get());
+ auto term1 = sameElement->get_terms()[1].get();
EXPECT_TRUE(term1 != nullptr);
}
@@ -75,15 +83,17 @@ TEST(SameElementQueryNodeTest, test_same_element_evaluate)
auto * sameElem = dynamic_cast<SameElementQueryNode *>(&q.getRoot());
EXPECT_TRUE(sameElem != nullptr);
EXPECT_EQ("field", sameElem->getIndex());
- EXPECT_EQ(3u, sameElem->size());
- verifyQueryTermNode("field.f1", (*sameElem)[0].get());
- verifyQueryTermNode("field.f2", (*sameElem)[1].get());
- verifyQueryTermNode("field.f3", (*sameElem)[2].get());
-
- QueryTermList terms;
- q.getLeaves(terms);
+ EXPECT_EQ(3u, sameElem->get_terms().size());
+ verifyQueryTermNode("field.f1", sameElem->get_terms()[0].get());
+ verifyQueryTermNode("field.f2", sameElem->get_terms()[1].get());
+ verifyQueryTermNode("field.f3", sameElem->get_terms()[2].get());
+
+ QueryTermList leaves;
+ q.getLeaves(leaves);
+ EXPECT_EQ(1u, leaves.size());
+ auto& terms = sameElem->get_terms();
EXPECT_EQ(3u, terms.size());
- for (QueryTerm * qt : terms) {
+ for (auto& qt : terms) {
qt->resizeFieldId(3);
}
@@ -130,6 +140,19 @@ TEST(SameElementQueryNodeTest, test_same_element_evaluate)
EXPECT_EQ(160, hits[3].element_weight());
EXPECT_EQ(0u, hits[3].position());
EXPECT_TRUE(sameElem->evaluate());
+
+ SimpleTermData td;
+ constexpr TermFieldHandle handle0 = 27;
+ constexpr TermFieldHandle handle_max = handle0;
+ td.addField(0).setHandle(handle0);
+ auto md = MatchData::makeTestInstance(handle_max + 1, handle_max + 1);
+ auto tfmd0 = md->resolveTermField(handle0);
+ tfmd0->setNeedInterleavedFeatures(true);
+ IndexEnvironment ie;
+ sameElem->unpack_match_data(2, td, *md, ie);
+ EXPECT_EQ(2, tfmd0->getDocId());
+ EXPECT_EQ(0, tfmd0->getNumOccs());
+ EXPECT_EQ(0, tfmd0->end() - tfmd0->begin());
}
GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/searchlib/src/vespa/searchlib/query/streaming/equiv_query_node.cpp b/searchlib/src/vespa/searchlib/query/streaming/equiv_query_node.cpp
index 3fcf983901d..8878c8c5cdc 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/equiv_query_node.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/equiv_query_node.cpp
@@ -81,10 +81,10 @@ EquivQueryNode::unpack_match_data(uint32_t docid, const fef::ITermData& td, fef:
unpack_match_data_helper(docid, td, match_data, hit_list, *this, is_filter(), index_env);
}
-EquivQueryNode*
-EquivQueryNode::as_equiv_query_node() noexcept
+bool
+EquivQueryNode::multi_index_terms() const noexcept
{
- return this;
+ return true;
}
const EquivQueryNode*
diff --git a/searchlib/src/vespa/searchlib/query/streaming/equiv_query_node.h b/searchlib/src/vespa/searchlib/query/streaming/equiv_query_node.h
index a0485954675..997a861ee44 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/equiv_query_node.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/equiv_query_node.h
@@ -17,7 +17,7 @@ public:
bool evaluate() const override;
const HitList & evaluateHits(HitList & hl) const override;
void unpack_match_data(uint32_t docid, const fef::ITermData& td, fef::MatchData& match_data, const fef::IIndexEnvironment& index_env) override;
- EquivQueryNode* as_equiv_query_node() noexcept override;
+ bool multi_index_terms() const noexcept override;
const EquivQueryNode* as_equiv_query_node() const noexcept override;
std::vector<std::unique_ptr<QueryTerm>> steal_terms();
};
diff --git a/searchlib/src/vespa/searchlib/query/streaming/multi_term.cpp b/searchlib/src/vespa/searchlib/query/streaming/multi_term.cpp
index f5a09892551..2a96a967215 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/multi_term.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/multi_term.cpp
@@ -51,4 +51,22 @@ MultiTerm::evaluate() const
return false;
}
+MultiTerm*
+MultiTerm::as_multi_term() noexcept
+{
+ return this;
+}
+
+const MultiTerm*
+MultiTerm::as_multi_term() const noexcept
+{
+ return this;
+}
+
+bool
+MultiTerm::multi_index_terms() const noexcept
+{
+ return false;
+}
+
}
diff --git a/searchlib/src/vespa/searchlib/query/streaming/multi_term.h b/searchlib/src/vespa/searchlib/query/streaming/multi_term.h
index 9bf5f8de6b2..a2ae3d30d52 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/multi_term.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/multi_term.h
@@ -29,7 +29,12 @@ public:
std::unique_ptr<query::TermVector> terms, Normalizing normalizing);
~MultiTerm() override;
void add_term(std::unique_ptr<QueryTerm> term);
- MultiTerm* as_multi_term() noexcept override { return this; }
+ MultiTerm* as_multi_term() noexcept override;
+ const MultiTerm* as_multi_term() const noexcept override;
+ /*
+ * Terms below search in different indexes when multi_index_terms() returns true.
+ */
+ virtual bool multi_index_terms() const noexcept;
void reset() override;
bool evaluate() const override;
const std::vector<std::unique_ptr<QueryTerm>>& get_terms() const noexcept { return _terms; }
diff --git a/searchlib/src/vespa/searchlib/query/streaming/query.cpp b/searchlib/src/vespa/searchlib/query/streaming/query.cpp
index 94d9acd02cd..25fcb8c123e 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/query.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/query.cpp
@@ -95,7 +95,6 @@ QueryConnector::create(ParseItem::ItemType type)
case search::ParseItem::ITEM_OR:
case search::ParseItem::ITEM_WEAK_AND: return std::make_unique<OrQueryNode>();
case search::ParseItem::ITEM_NOT: return std::make_unique<AndNotQueryNode>();
- case search::ParseItem::ITEM_SAME_ELEMENT: return std::make_unique<SameElementQueryNode>();
case search::ParseItem::ITEM_NEAR: return std::make_unique<NearQueryNode>();
case search::ParseItem::ITEM_ONEAR: return std::make_unique<ONearQueryNode>();
case search::ParseItem::ITEM_RANK: return std::make_unique<RankWithQueryNode>();
diff --git a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
index 611e8d67d76..94a479fd2d3 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
@@ -11,6 +11,7 @@
#include <vespa/searchlib/query/streaming/dot_product_term.h>
#include <vespa/searchlib/query/streaming/equiv_query_node.h>
#include <vespa/searchlib/query/streaming/in_term.h>
+#include <vespa/searchlib/query/streaming/same_element_query_node.h>
#include <vespa/searchlib/query/streaming/wand_term.h>
#include <vespa/searchlib/query/streaming/weighted_set_term.h>
#include <vespa/searchlib/query/tree/term_vector.h>
@@ -26,9 +27,7 @@ namespace search::streaming {
namespace {
bool disableRewrite(const QueryNode * qn) {
- return dynamic_cast<const NearQueryNode *> (qn) ||
- dynamic_cast<const PhraseQueryNode *> (qn) ||
- dynamic_cast<const SameElementQueryNode *>(qn);
+ return dynamic_cast<const NearQueryNode *> (qn);
}
bool possibleFloat(const QueryTerm & qt, const QueryTerm::string & term) {
@@ -49,7 +48,6 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor
case ParseItem::ITEM_OR:
case ParseItem::ITEM_WEAK_AND:
case ParseItem::ITEM_NOT:
- case ParseItem::ITEM_SAME_ELEMENT:
case ParseItem::ITEM_NEAR:
case ParseItem::ITEM_ONEAR:
case ParseItem::ITEM_RANK:
@@ -61,9 +59,7 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor
if (nqn) {
nqn->distance(queryRep.getNearDistance());
}
- if ((type == ParseItem::ITEM_WEAK_AND) ||
- (type == ParseItem::ITEM_SAME_ELEMENT))
- {
+ if (type == ParseItem::ITEM_WEAK_AND) {
qn->setIndex(queryRep.getIndexName());
}
for (size_t i=0; i < arity; i++) {
@@ -197,6 +193,9 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor
case ParseItem::ITEM_EQUIV:
qn = build_equiv_term(factory, queryRep, allowRewrite);
break;
+ case ParseItem::ITEM_SAME_ELEMENT:
+ qn = build_same_element_term(factory, queryRep);
+ break;
default:
skip_unknown(queryRep);
break;
@@ -335,6 +334,25 @@ QueryNode::build_equiv_term(const QueryNodeResultFactory& factory, SimpleQuerySt
return eqn;
}
+std::unique_ptr<QueryNode>
+QueryNode::build_same_element_term(const QueryNodeResultFactory& factory, SimpleQueryStackDumpIterator& queryRep)
+{
+ auto sen = std::make_unique<SameElementQueryNode>(factory.create(), queryRep.getIndexName(), queryRep.getArity());
+ auto arity = queryRep.getArity();
+ sen->setWeight(queryRep.GetWeight());
+ sen->setUniqueId(queryRep.getUniqueId());
+ for (size_t i = 0; i < arity; ++i) {
+ queryRep.next();
+ auto qn = Build(sen.get(), factory, queryRep, false);
+ auto qtp = dynamic_cast<QueryTerm*>(qn.get());
+ assert(qtp != nullptr);
+ qn.release();
+ std::unique_ptr<QueryTerm> qt(qtp);
+ sen->add_term(std::move(qt));
+ }
+ return sen;
+}
+
void
QueryNode::skip_unknown(SimpleQueryStackDumpIterator& queryRep)
{
diff --git a/searchlib/src/vespa/searchlib/query/streaming/querynode.h b/searchlib/src/vespa/searchlib/query/streaming/querynode.h
index fff3bb15d10..20e701e5c50 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/querynode.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/querynode.h
@@ -35,6 +35,7 @@ class QueryNode
static std::unique_ptr<QueryNode> build_weighted_set_term(const QueryNodeResultFactory& factory, SimpleQueryStackDumpIterator& queryRep);
static std::unique_ptr<QueryNode> build_phrase_term(const QueryNodeResultFactory& factory, SimpleQueryStackDumpIterator& queryRep);
static std::unique_ptr<QueryNode> build_equiv_term(const QueryNodeResultFactory& factory, SimpleQueryStackDumpIterator& queryRep, bool allow_rewrite);
+ static std::unique_ptr<QueryNode> build_same_element_term(const QueryNodeResultFactory& factory, SimpleQueryStackDumpIterator& queryRep);
static void skip_unknown(SimpleQueryStackDumpIterator& queryRep);
public:
using UP = std::unique_ptr<QueryNode>;
diff --git a/searchlib/src/vespa/searchlib/query/streaming/queryterm.cpp b/searchlib/src/vespa/searchlib/query/streaming/queryterm.cpp
index 728b9a2ab76..07fc60d2243 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/queryterm.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/queryterm.cpp
@@ -135,20 +135,20 @@ QueryTerm::as_multi_term() noexcept
return nullptr;
}
-RegexpTerm*
-QueryTerm::as_regexp_term() noexcept
+const MultiTerm*
+QueryTerm::as_multi_term() const noexcept
{
return nullptr;
}
-FuzzyTerm*
-QueryTerm::as_fuzzy_term() noexcept
+RegexpTerm*
+QueryTerm::as_regexp_term() noexcept
{
return nullptr;
}
-EquivQueryNode*
-QueryTerm::as_equiv_query_node() noexcept
+FuzzyTerm*
+QueryTerm::as_fuzzy_term() noexcept
{
return nullptr;
}
diff --git a/searchlib/src/vespa/searchlib/query/streaming/queryterm.h b/searchlib/src/vespa/searchlib/query/streaming/queryterm.h
index e6b063231d6..78b0a1fea7d 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/queryterm.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/queryterm.h
@@ -104,9 +104,9 @@ public:
void setFuzzyPrefixLength(uint32_t fuzzyPrefixLength) { _fuzzyPrefixLength = fuzzyPrefixLength; }
virtual NearestNeighborQueryNode* as_nearest_neighbor_query_node() noexcept;
virtual MultiTerm* as_multi_term() noexcept;
+ virtual const MultiTerm* as_multi_term() const noexcept;
virtual RegexpTerm* as_regexp_term() noexcept;
virtual FuzzyTerm* as_fuzzy_term() noexcept;
- virtual EquivQueryNode* as_equiv_query_node() noexcept;
virtual const EquivQueryNode* as_equiv_query_node() const noexcept;
virtual void unpack_match_data(uint32_t docid, const fef::ITermData& td, fef::MatchData& match_data, const fef::IIndexEnvironment& index_env);
protected:
diff --git a/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp b/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp
index 49d5fb0f9fb..cd9c693ca1c 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp
@@ -1,30 +1,36 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "same_element_query_node.h"
+#include <vespa/searchlib/fef/itermdata.h>
+#include <vespa/searchlib/fef/matchdata.h>
#include <cassert>
namespace search::streaming {
+SameElementQueryNode::SameElementQueryNode(std::unique_ptr<QueryNodeResultBase> result_base, const string& index, uint32_t num_terms) noexcept
+ : MultiTerm(std::move(result_base), index, num_terms)
+{
+}
+
+SameElementQueryNode::~SameElementQueryNode() = default;
+
bool
SameElementQueryNode::evaluate() const {
HitList hl;
return ! evaluateHits(hl).empty();
}
-void
-SameElementQueryNode::addChild(QueryNode::UP child) {
- assert(dynamic_cast<const QueryTerm *>(child.get()) != nullptr);
- AndQueryNode::addChild(std::move(child));
-}
-
const HitList &
SameElementQueryNode::evaluateHits(HitList & hl) const
{
hl.clear();
- if ( !AndQueryNode::evaluate()) return hl;
-
+ const auto & children = get_terms();
+ for (auto& child : children) {
+ if ( ! child->evaluate() ) {
+ return hl;
+ }
+ }
HitList tmpHL;
- const auto & children = getChildren();
unsigned int numFields = children.size();
unsigned int currMatchCount = 0;
std::vector<unsigned int> indexVector(numFields, 0);
@@ -62,4 +68,31 @@ SameElementQueryNode::evaluateHits(HitList & hl) const
return hl;
}
+void
+SameElementQueryNode::unpack_match_data(uint32_t docid, const fef::ITermData& td, fef::MatchData& match_data, const fef::IIndexEnvironment&)
+{
+ HitList list;
+ const HitList & hit_list = evaluateHits(list);
+ if (!hit_list.empty()) {
+ auto num_fields = td.numFields();
+ /*
+ * Currently reports hit for all fields for query node instead of
+ * just the fields where the related subfields had matches.
+ */
+ for (size_t field_idx = 0; field_idx < num_fields; ++field_idx) {
+ auto& tfd = td.field(field_idx);
+ auto field_id = tfd.getFieldId();
+ auto tmd = match_data.resolveTermField(tfd.getHandle());
+ tmd->setFieldId(field_id);
+ tmd->reset(docid);
+ }
+ }
+}
+
+bool
+SameElementQueryNode::multi_index_terms() const noexcept
+{
+ return true;
+}
+
}
diff --git a/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.h b/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.h
index 8e675feb569..37fb3dbba52 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.h
@@ -2,21 +2,22 @@
#pragma once
-#include "query.h"
+#include "multi_term.h"
namespace search::streaming {
/**
N-ary Same element operator. All terms must be within the same element.
*/
-class SameElementQueryNode : public AndQueryNode
+class SameElementQueryNode : public MultiTerm
{
public:
- SameElementQueryNode() noexcept : AndQueryNode("SAME_ELEMENT") { }
+ SameElementQueryNode(std::unique_ptr<QueryNodeResultBase> result_base, const string& index, uint32_t num_terms) noexcept;
+ ~SameElementQueryNode() override;
bool evaluate() const override;
const HitList & evaluateHits(HitList & hl) const override;
- bool isFlattenable(ParseItem::ItemType) const override { return false; }
- void addChild(QueryNode::UP child) override;
+ void unpack_match_data(uint32_t docid, const fef::ITermData& td, fef::MatchData& match_data, const fef::IIndexEnvironment& index_env) override;
+ bool multi_index_terms() const noexcept override;
};
}
diff --git a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp
index 2a95bf8251b..cfaaac8b197 100644
--- a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp
+++ b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp
@@ -56,7 +56,7 @@ getFeature(const RankProgram &rankProgram) {
}
void
-RankProcessor::resolve_fields_from_children(QueryTermData& qtd, MultiTerm& mt)
+RankProcessor::resolve_fields_from_children(QueryTermData& qtd, const MultiTerm& mt)
{
vespalib::hash_set<uint32_t> field_ids;
for (auto& subterm : mt.get_terms()) {
@@ -83,7 +83,7 @@ RankProcessor::resolve_fields_from_children(QueryTermData& qtd, MultiTerm& mt)
}
void
-RankProcessor::resolve_fields_from_term(QueryTermData& qtd, search::streaming::QueryTerm& term)
+RankProcessor::resolve_fields_from_term(QueryTermData& qtd, const search::streaming::QueryTerm& term)
{
vespalib::string expandedIndexName = vsm::FieldSearchSpecMap::stripNonFields(term.index());
const RankManager::View *view = _rankManagerSnapshot->getView(expandedIndexName);
diff --git a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h
index f384f7d7acf..9cb3e49fc32 100644
--- a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h
+++ b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h
@@ -45,8 +45,8 @@ private:
HitCollector::UP _hitCollector;
std::unique_ptr<RankProgram> _match_features_program;
- void resolve_fields_from_children(QueryTermData& qtd, search::streaming::MultiTerm& mt);
- void resolve_fields_from_term(QueryTermData& qtd, search::streaming::QueryTerm& term);
+ void resolve_fields_from_children(QueryTermData& qtd, const search::streaming::MultiTerm& mt);
+ void resolve_fields_from_term(QueryTermData& qtd, const search::streaming::QueryTerm& term);
void initQueryEnvironment();
void initHitCollector(size_t wantedHitCount, bool use_sort_blob);
void setupRankProgram(search::fef::RankProgram &program);
diff --git a/streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.cpp b/streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.cpp
index 72807bc6c34..38e12a3054d 100644
--- a/streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.cpp
+++ b/streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.cpp
@@ -192,9 +192,9 @@ FieldSearcher::init()
void
FieldIdTSearcherMap::prepare_term(const DocumentTypeIndexFieldMapT& difm, QueryTerm* qt, FieldIdT fid, vespalib::hash_set<const void*>& seen, QueryTermList& onlyInIndex)
{
- auto equiv = qt->as_equiv_query_node();
- if (equiv != nullptr) {
- for (auto& subterm : equiv->get_terms()) {
+ auto multi_term = qt->as_multi_term();
+ if (multi_term != nullptr && multi_term->multi_index_terms()) {
+ for (auto& subterm : multi_term->get_terms()) {
prepare_term(difm, subterm.get(), fid, seen, onlyInIndex);
}
return;
@@ -206,7 +206,6 @@ FieldIdTSearcherMap::prepare_term(const DocumentTypeIndexFieldMapT& difm, QueryT
const FieldIdTList & index = found->second;
if ((find(index.begin(), index.end(), fid) != index.end()) && !seen.contains(qt)) {
seen.insert(qt);
- auto multi_term = qt->as_multi_term();
if (multi_term != nullptr) {
for (auto& subterm : multi_term->get_terms()) {
onlyInIndex.emplace_back(subterm.get());
diff --git a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
index c596b46a774..1dbac859262 100644
--- a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
+++ b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
@@ -223,9 +223,9 @@ FieldSearchSpecMap::buildFieldsInQuery(const Query & query) const
query.getLeaves(qtl);
for (const auto & term : qtl) {
- auto equiv = term->as_equiv_query_node();
- if (equiv != nullptr) {
- for (const auto& subterm : equiv->get_terms()) {
+ auto multi_term = term->as_multi_term();
+ if (multi_term != nullptr && multi_term->multi_index_terms()) {
+ for (const auto& subterm : multi_term->get_terms()) {
addFieldsFromIndex(subterm->index(), fieldsInQuery);
}
} else {