aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib
diff options
context:
space:
mode:
Diffstat (limited to 'searchlib/src/vespa/searchlib')
-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
11 files changed, 109 insertions, 34 deletions
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;
};
}