aboutsummaryrefslogtreecommitdiffstats
path: root/streamingvisitors
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2024-02-09 13:12:45 +0100
committerTor Egge <Tor.Egge@online.no>2024-02-09 13:12:45 +0100
commit332bdd44a075c16418b49ddfe66965e5a46e2e8c (patch)
treed1a848f04b0deda0937687a041898faf55f199f8 /streamingvisitors
parent6e03787d79b327915dff98815db777d879986396 (diff)
Handle search::streaming::EquivQueryNode as a leaf in the query tree.
Diffstat (limited to 'streamingvisitors')
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp64
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/rankprocessor.h4
-rw-r--r--streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.cpp57
-rw-r--r--streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.h2
-rw-r--r--streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp10
5 files changed, 100 insertions, 37 deletions
diff --git a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp
index 3449df57513..a54d2adee78 100644
--- a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp
+++ b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.cpp
@@ -4,7 +4,7 @@
#include "rankprocessor.h"
#include <vespa/searchlib/fef/handle.h>
#include <vespa/searchlib/fef/simpletermfielddata.h>
-#include <vespa/searchlib/query/streaming/multi_term.h>
+#include <vespa/searchlib/query/streaming/equiv_query_node.h>
#include <vespa/searchlib/query/streaming/nearest_neighbor_query_node.h>
#include <vespa/vsm/vsm/fieldsearchspec.h>
#include <algorithm>
@@ -56,6 +56,51 @@ getFeature(const RankProgram &rankProgram) {
}
void
+RankProcessor::resolve_fields_from_children(QueryTermData& qtd, MultiTerm& mt)
+{
+ vespalib::hash_set<uint32_t> field_ids;
+ for (auto& subterm : mt.get_terms()) {
+ vespalib::string expandedIndexName = vsm::FieldSearchSpecMap::stripNonFields(subterm->index());
+ const RankManager::View *view = _rankManagerSnapshot->getView(expandedIndexName);
+ if (view != nullptr) {
+ for (auto field_id : *view) {
+ field_ids.insert(field_id);
+ }
+ } else {
+ LOG(warning, "Could not find a view for index '%s'. Ranking no fields.",
+ getIndexName(subterm->index(), expandedIndexName).c_str());
+ }
+ }
+ std::vector<uint32_t> sorted_field_ids;
+ sorted_field_ids.reserve(field_ids.size());
+ for (auto field_id : field_ids) {
+ sorted_field_ids.emplace_back(field_id);
+ }
+ std::sort(sorted_field_ids.begin(), sorted_field_ids.end());
+ for (auto field_id : sorted_field_ids) {
+ qtd.getTermData().addField(field_id).setHandle(_mdLayout.allocTermField(field_id));
+ }
+}
+
+void
+RankProcessor::resolve_fields_from_term(QueryTermData& qtd, search::streaming::QueryTerm& term)
+{
+ vespalib::string expandedIndexName = vsm::FieldSearchSpecMap::stripNonFields(term.index());
+ const RankManager::View *view = _rankManagerSnapshot->getView(expandedIndexName);
+ if (view != nullptr) {
+ for (auto field_id : *view) {
+ qtd.getTermData().addField(field_id).setHandle(_mdLayout.allocTermField(field_id));
+ }
+ } else {
+ LOG(warning, "Could not find a view for index '%s'. Ranking no fields.",
+ getIndexName(term.index(), expandedIndexName).c_str());
+ }
+ LOG(debug, "Setup query term '%s:%s'",
+ getIndexName(term.index(), expandedIndexName).c_str(),
+ term.getTerm());
+}
+
+void
RankProcessor::initQueryEnvironment()
{
QueryWrapper::TermList & terms = _query.getTermList();
@@ -75,21 +120,12 @@ RankProcessor::initQueryEnvironment()
if (nn_term != nullptr) {
qtd.getTermData().set_query_tensor_name(nn_term->get_query_tensor_name());
}
-
- vespalib::string expandedIndexName = vsm::FieldSearchSpecMap::stripNonFields(term->index());
- const RankManager::View *view = _rankManagerSnapshot->getView(expandedIndexName);
- if (view != nullptr) {
- for (auto field_id : *view) {
- qtd.getTermData().addField(field_id).setHandle(_mdLayout.allocTermField(field_id));
- }
+ auto* eqn = term->as_equiv_query_node();
+ if (eqn != nullptr) {
+ resolve_fields_from_children(qtd, *eqn);
} else {
- LOG(warning, "Could not find a view for index '%s'. Ranking no fields.",
- getIndexName(term->index(), expandedIndexName).c_str());
+ resolve_fields_from_term(qtd, *term);
}
-
- LOG(debug, "Setup query term '%s:%s'",
- getIndexName(term->index(), expandedIndexName).c_str(),
- term->getTerm());
_queryEnv.addTerm(&qtd.getTermData());
}
_rankSetup.prepareSharedState(_queryEnv, _queryEnv.getObjectStore());
diff --git a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h
index 5651917ce7a..bec70beca77 100644
--- a/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h
+++ b/streamingvisitors/src/vespa/searchvisitor/rankprocessor.h
@@ -16,6 +16,8 @@
namespace streaming {
+class QueryTermData;
+
/**
* This class is associated with a query and a rank profile and
* is used to calculate rank and feature set for matched documents.
@@ -43,6 +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 initQueryEnvironment();
void initHitCollector(size_t wantedHitCount);
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 c75ab7fccd3..72807bc6c34 100644
--- a/streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.cpp
+++ b/streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.cpp
@@ -3,7 +3,7 @@
#include <vespa/vsm/vsm/fieldsearchspec.h>
#include <vespa/document/fieldvalue/arrayfieldvalue.h>
#include <vespa/document/fieldvalue/weightedsetfieldvalue.h>
-#include <vespa/searchlib/query/streaming/multi_term.h>
+#include <vespa/searchlib/query/streaming/equiv_query_node.h>
#include <vespa/vespalib/stllike/hash_set.h>
#include <cassert>
@@ -190,6 +190,39 @@ 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()) {
+ prepare_term(difm, subterm.get(), fid, seen, onlyInIndex);
+ }
+ return;
+ }
+ for (const auto& doc_type_elem : difm) {
+ const IndexFieldMapT & fim = doc_type_elem.second;
+ auto found = fim.find(FieldSearchSpecMap::stripNonFields(qt->index()));
+ if (found != fim.end()) {
+ 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());
+ }
+ } else {
+ onlyInIndex.emplace_back(qt);
+ }
+ }
+ } else {
+ LOG(debug, "Could not find the requested index=%s in the index config map. Query does not fit search definition.",
+ qt->index().c_str());
+ }
+ }
+}
+
+void
FieldIdTSearcherMap::prepare(const DocumentTypeIndexFieldMapT& difm, const SharedSearcherBuf& searcherBuf,
Query& query, const vsm::FieldPathMapT& field_paths,
search::fef::IQueryEnvironment& query_env)
@@ -202,27 +235,7 @@ FieldIdTSearcherMap::prepare(const DocumentTypeIndexFieldMapT& difm, const Share
vespalib::hash_set<const void*> seen;
FieldIdT fid = searcher->field();
for (auto qt : qtl) {
- for (const auto& doc_type_elem : difm) {
- const IndexFieldMapT & fim = doc_type_elem.second;
- auto found = fim.find(FieldSearchSpecMap::stripNonFields(qt->index()));
- if (found != fim.end()) {
- 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());
- }
- } else {
- onlyInIndex.emplace_back(qt);
- }
- }
- } else {
- LOG(debug, "Could not find the requested index=%s in the index config map. Query does not fit search definition.",
- qt->index().c_str());
- }
- }
+ prepare_term(difm, qt, fid, seen, onlyInIndex);
}
/// Should perhaps do a unique on onlyInIndex
searcher->prepare(onlyInIndex, searcherBuf, field_paths, query_env);
diff --git a/streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.h b/streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.h
index 6f3ec3e1e73..042e47ef164 100644
--- a/streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.h
+++ b/streamingvisitors/src/vespa/vsm/searcher/fieldsearcher.h
@@ -5,6 +5,7 @@
#include <vespa/searchlib/query/streaming/query.h>
#include <vespa/vsm/common/document.h>
#include <vespa/vsm/common/storagedocument.h>
+#include <vespa/vespalib/stllike/hash_set.h>
#include <vespa/vespalib/util/array.h>
#include <utility>
@@ -122,6 +123,7 @@ using FieldIdTSearcherMapT = std::vector<FieldSearcherContainer>;
class FieldIdTSearcherMap : public FieldIdTSearcherMapT
{
+ void prepare_term(const DocumentTypeIndexFieldMapT& difm, search::streaming::QueryTerm* qt, FieldIdT fid, vespalib::hash_set<const void*>& seen, search::streaming::QueryTermList& onlyInIndex);
public:
void prepare(const DocumentTypeIndexFieldMapT& difm, const SharedSearcherBuf& searcherBuf,
search::streaming::Query& query, const vsm::FieldPathMapT& field_paths,
diff --git a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
index 3ae4794e33f..c596b46a774 100644
--- a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
+++ b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "fieldsearchspec.h"
+#include <vespa/searchlib/query/streaming/equiv_query_node.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/vsm/searcher/boolfieldsearcher.h>
#include <vespa/vsm/searcher/floatfieldsearcher.h>
@@ -222,7 +223,14 @@ FieldSearchSpecMap::buildFieldsInQuery(const Query & query) const
query.getLeaves(qtl);
for (const auto & term : qtl) {
- addFieldsFromIndex(term->index(), fieldsInQuery);
+ auto equiv = term->as_equiv_query_node();
+ if (equiv != nullptr) {
+ for (const auto& subterm : equiv->get_terms()) {
+ addFieldsFromIndex(subterm->index(), fieldsInQuery);
+ }
+ } else {
+ addFieldsFromIndex(term->index(), fieldsInQuery);
+ }
}
return fieldsInQuery;
}