diff options
Diffstat (limited to 'searchlib/src')
5 files changed, 40 insertions, 22 deletions
diff --git a/searchlib/src/tests/nearsearch/nearsearch_test.cpp b/searchlib/src/tests/nearsearch/nearsearch_test.cpp index 3751fc93cea..95701e59444 100644 --- a/searchlib/src/tests/nearsearch/nearsearch_test.cpp +++ b/searchlib/src/tests/nearsearch/nearsearch_test.cpp @@ -215,7 +215,7 @@ bool Test::testNearSearch(MyQuery &query, uint32_t matchId) { LOG(info, "testNearSearch(%d)", matchId); - search::queryeval::IntermediateBlueprint *near_b = 0; + search::queryeval::IntermediateBlueprint *near_b = nullptr; if (query.isOrdered()) { near_b = new search::queryeval::ONearBlueprint(query.getWindow()); } else { @@ -228,9 +228,10 @@ Test::testNearSearch(MyQuery &query, uint32_t matchId) layout.allocTermField(fieldId); near_b->addChild(query.getTerm(i).make_blueprint(fieldId, i)); } - search::fef::MatchData::UP md(layout.createMatchData()); - + bp->setDocIdLimit(1000); + bp = search::queryeval::Blueprint::optimize_and_sort(std::move(bp), true, true); bp->fetchPostings(search::queryeval::ExecuteInfo::TRUE); + search::fef::MatchData::UP md(layout.createMatchData()); search::queryeval::SearchIterator::UP near = bp->createSearch(*md, true); near->initFullRange(); bool foundMatch = false; diff --git a/searchlib/src/vespa/searchlib/query/streaming/query.cpp b/searchlib/src/vespa/searchlib/query/streaming/query.cpp index 679141dbc2f..5b0076a30c5 100644 --- a/searchlib/src/vespa/searchlib/query/streaming/query.cpp +++ b/searchlib/src/vespa/searchlib/query/streaming/query.cpp @@ -117,6 +117,7 @@ QueryConnector::create(ParseItem::ItemType type) 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>(); default: return nullptr; } } @@ -162,6 +163,18 @@ OrQueryNode::evaluate() const { return false; } +bool +RankWithQueryNode::evaluate() const { + bool first = true; + bool firstOk = false; + for (const auto & qn : getChildren()) { + if (qn->evaluate()) { + if (first) firstOk = true; + } + first = false; + } + return firstOk; +} bool EquivQueryNode::evaluate() const diff --git a/searchlib/src/vespa/searchlib/query/streaming/query.h b/searchlib/src/vespa/searchlib/query/streaming/query.h index 0f15c536d44..4ab33a01d86 100644 --- a/searchlib/src/vespa/searchlib/query/streaming/query.h +++ b/searchlib/src/vespa/searchlib/query/streaming/query.h @@ -95,6 +95,18 @@ public: }; /** + N-ary RankWith operator +*/ +class RankWithQueryNode : public QueryConnector +{ +public: + RankWithQueryNode() noexcept : QueryConnector("RANK") { } + explicit RankWithQueryNode(const char * opName) noexcept : QueryConnector(opName) { } + bool evaluate() const override; +}; + + +/** N-ary "EQUIV" operator that merges terms from nodes below. */ class EquivQueryNode : public OrQueryNode diff --git a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp index 6ef63dcdd7a..32e3ec16b16 100644 --- a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp +++ b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp @@ -51,6 +51,7 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor case ParseItem::ITEM_SAME_ELEMENT: case ParseItem::ITEM_NEAR: case ParseItem::ITEM_ONEAR: + case ParseItem::ITEM_RANK: { qn = QueryConnector::create(type); if (qn) { @@ -176,17 +177,6 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor } } break; - case ParseItem::ITEM_RANK: - { - if (arity >= 1) { - queryRep.next(); - qn = Build(parent, factory, queryRep, false); - for (uint32_t skipCount = arity-1; (skipCount > 0) && queryRep.next(); skipCount--) { - skipCount += queryRep.getArity(); - } - } - } - break; case ParseItem::ITEM_STRING_IN: qn = std::make_unique<InTerm>(factory.create(), queryRep.getIndexName(), queryRep.get_terms(), factory.normalizing_mode(queryRep.getIndexName())); diff --git a/searchlib/src/vespa/searchlib/queryeval/nearsearch.cpp b/searchlib/src/vespa/searchlib/queryeval/nearsearch.cpp index 1f83075b9fc..8fc7733f279 100644 --- a/searchlib/src/vespa/searchlib/queryeval/nearsearch.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/nearsearch.cpp @@ -3,7 +3,7 @@ #include <vespa/vespalib/objects/visit.h> #include <vespa/vespalib/util/priority_queue.h> #include <limits> -#include <set> +#include <map> #include <vespa/log/log.h> LOG_SETUP(".nearsearch"); @@ -16,13 +16,15 @@ using search::fef::TermFieldMatchDataArray; using search::fef::TermFieldMatchDataPositionKey; template<typename T> -void setup_fields(uint32_t window, std::vector<T> &matchers, const TermFieldMatchDataArray &in) { - std::set<uint32_t> fields; +void setup_fields(uint32_t window, std::vector<T> &matchers, const TermFieldMatchDataArray &in, uint32_t terms) { + std::map<uint32_t,uint32_t> fields; for (size_t i = 0; i < in.size(); ++i) { - fields.insert(in[i]->getFieldId()); + ++fields[in[i]->getFieldId()]; } - for (const auto& elem : fields) { - matchers.push_back(T(window, elem, in)); + for (auto [field, cnt]: fields) { + if (cnt == terms) { + matchers.push_back(T(window, field, in)); + } } } @@ -126,7 +128,7 @@ NearSearch::NearSearch(Children terms, : NearSearchBase(std::move(terms), data, window, strict), _matchers() { - setup_fields(window, _matchers, data); + setup_fields(window, _matchers, data, getChildren().size()); } namespace { @@ -227,7 +229,7 @@ ONearSearch::ONearSearch(Children terms, : NearSearchBase(std::move(terms), data, window, strict), _matchers() { - setup_fields(window, _matchers, data); + setup_fields(window, _matchers, data, getChildren().size()); } bool |