aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src
diff options
context:
space:
mode:
Diffstat (limited to 'searchlib/src')
-rw-r--r--searchlib/src/tests/nearsearch/nearsearch_test.cpp7
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/query.cpp13
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/query.h12
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/querynode.cpp12
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/nearsearch.cpp18
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