summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2019-10-02 14:16:29 +0000
committerHåvard Pettersen <havardpe@oath.com>2019-10-02 14:30:51 +0000
commit8c9ddd4a626e43d564c1aea343a7cf706c486fee (patch)
treedf70a4b754439741d882b58d0d2acf79b00adfd2
parentf2779a77280698ff06c5fe3b1b85d34b95180a6e (diff)
collect matching elements by using SameElement blueprints
-rw-r--r--searchcore/src/tests/proton/matching/same_element_builder/same_element_builder_test.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/docsum_matcher.cpp52
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/same_element_builder.cpp5
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/same_element_builder.h3
-rw-r--r--searchlib/src/tests/queryeval/same_element/same_element_test.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/common/struct_field_mapper.h1
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp22
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h7
9 files changed, 75 insertions, 21 deletions
diff --git a/searchcore/src/tests/proton/matching/same_element_builder/same_element_builder_test.cpp b/searchcore/src/tests/proton/matching/same_element_builder/same_element_builder_test.cpp
index 6583f3bc00b..3eff38fbf20 100644
--- a/searchcore/src/tests/proton/matching/same_element_builder/same_element_builder_test.cpp
+++ b/searchcore/src/tests/proton/matching/same_element_builder/same_element_builder_test.cpp
@@ -90,7 +90,7 @@ struct BuilderFixture {
FakeRequestContext req_ctx;
FakeSearchContext ctx;
SameElementBuilder builder;
- BuilderFixture() : req_ctx(), ctx(), builder(req_ctx, ctx, false) {
+ BuilderFixture() : req_ctx(), ctx(), builder(req_ctx, ctx, "foo", false) {
ctx.attr().tag("attr");
ctx.addIdx(0).idx(0).getFake().tag("idx");
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
index 380aeb82ad2..7e55c8f778c 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
@@ -102,7 +102,7 @@ private:
}
void buildSameElement(ProtonSameElement &n) {
- SameElementBuilder builder(_requestContext, _context, n.is_expensive());
+ SameElementBuilder builder(_requestContext, _context, n.getView(), n.is_expensive());
for (search::query::Node *node : n.getChildren()) {
builder.add_child(*node);
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/docsum_matcher.cpp b/searchcore/src/vespa/searchcore/proton/matching/docsum_matcher.cpp
index 73aab5b3fca..34310371755 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/docsum_matcher.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/docsum_matcher.cpp
@@ -4,15 +4,23 @@
#include <vespa/eval/eval/tensor.h>
#include <vespa/eval/eval/tensor_engine.h>
#include <vespa/vespalib/objects/nbostream.h>
+#include <vespa/searchlib/queryeval/blueprint.h>
+#include <vespa/searchlib/queryeval/intermediate_blueprints.h>
+#include <vespa/searchlib/queryeval/same_element_blueprint.h>
+#include <vespa/searchlib/queryeval/same_element_search.h>
#include <vespa/log/log.h>
LOG_SETUP(".proton.matching.docsum_matcher");
using search::FeatureSet;
-using search::StructFieldMapper;
using search::MatchingElements;
-using search::fef::RankProgram;
+using search::StructFieldMapper;
using search::fef::FeatureResolver;
+using search::fef::RankProgram;
+using search::queryeval::AndNotBlueprint;
+using search::queryeval::Blueprint;
+using search::queryeval::IntermediateBlueprint;
+using search::queryeval::SameElementBlueprint;
using search::queryeval::SearchIterator;
namespace proton::matching {
@@ -74,6 +82,36 @@ FeatureSet::UP get_feature_set(const MatchToolsFactory &mtf,
return retval;
}
+template<typename T>
+const T *as(const Blueprint &bp) { return dynamic_cast<const T *>(&bp); }
+
+void find_matching_elements(const std::vector<uint32_t> &docs, const SameElementBlueprint &same_element, MatchingElements &result) {
+ auto search = same_element.create_same_element_search(false);
+ search->initRange(docs.front(), docs.back()+1);
+ std::vector<uint32_t> matches;
+ for (uint32_t i = 0; i < docs.size(); ++i) {
+ search->find_matching_elements(docs[i], matches);
+ if (!matches.empty()) {
+ result.add_matching_elements(docs[i], same_element.struct_field_name(), matches);
+ matches.clear();
+ }
+ }
+}
+
+void find_matching_elements(const StructFieldMapper &mapper, const std::vector<uint32_t> &docs, const Blueprint &bp, MatchingElements &result) {
+ if (auto same_element = as<SameElementBlueprint>(bp)) {
+ if (mapper.is_struct_field(same_element->struct_field_name())) {
+ find_matching_elements(docs, *same_element, result);
+ }
+ } else if (auto and_not = as<AndNotBlueprint>(bp)) {
+ find_matching_elements(mapper, docs, and_not->getChild(0), result);
+ } else if (auto intermediate = as<IntermediateBlueprint>(bp)) {
+ for (size_t i = 0; i < intermediate->childCnt(); ++i) {
+ find_matching_elements(mapper, docs, intermediate->getChild(i), result);
+ }
+ }
+}
+
}
DocsumMatcher::DocsumMatcher()
@@ -127,11 +165,13 @@ DocsumMatcher::get_rank_features() const
MatchingElements::UP
DocsumMatcher::get_matching_elements(const StructFieldMapper &field_mapper) const
{
- if (!_mtf) {
- return std::make_unique<MatchingElements>();
+ auto result = std::make_unique<MatchingElements>();
+ if (_mtf && !field_mapper.empty()) {
+ if (const Blueprint *root = _mtf->query().peekRoot()) {
+ find_matching_elements(field_mapper, _docs, *root, *result);
+ }
}
- (void) field_mapper;
- return std::make_unique<MatchingElements>();
+ return result;
}
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/same_element_builder.cpp b/searchcore/src/vespa/searchcore/proton/matching/same_element_builder.cpp
index 8e012c52b5f..241ab53874f 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/same_element_builder.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/same_element_builder.cpp
@@ -71,10 +71,11 @@ public:
} // namespace proton::matching::<unnamed>
-SameElementBuilder::SameElementBuilder(const search::queryeval::IRequestContext &requestContext, ISearchContext &context, bool expensive)
+SameElementBuilder::SameElementBuilder(const search::queryeval::IRequestContext &requestContext, ISearchContext &context,
+ const vespalib::string &struct_field_name, bool expensive)
: _requestContext(requestContext),
_context(context),
- _result(std::make_unique<SameElementBlueprint>(expensive))
+ _result(std::make_unique<SameElementBlueprint>(struct_field_name, expensive))
{
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/same_element_builder.h b/searchcore/src/vespa/searchcore/proton/matching/same_element_builder.h
index b9cfff8a9c0..c68bdfced99 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/same_element_builder.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/same_element_builder.h
@@ -16,7 +16,8 @@ private:
ISearchContext &_context;
std::unique_ptr<search::queryeval::SameElementBlueprint> _result;
public:
- SameElementBuilder(const search::queryeval::IRequestContext &requestContext, ISearchContext &context, bool expensive);
+ SameElementBuilder(const search::queryeval::IRequestContext &requestContext, ISearchContext &context,
+ const vespalib::string &struct_field_name, bool expensive);
void add_child(search::query::Node &node);
search::queryeval::Blueprint::UP build();
};
diff --git a/searchlib/src/tests/queryeval/same_element/same_element_test.cpp b/searchlib/src/tests/queryeval/same_element/same_element_test.cpp
index 622c8077c14..a4ca1ade999 100644
--- a/searchlib/src/tests/queryeval/same_element/same_element_test.cpp
+++ b/searchlib/src/tests/queryeval/same_element/same_element_test.cpp
@@ -23,7 +23,7 @@ void verify_elements(SameElementSearch &se, uint32_t docid, const std::initializ
}
std::unique_ptr<SameElementBlueprint> make_blueprint(const std::vector<FakeResult> &children, bool fake_attr = false) {
- auto result = std::make_unique<SameElementBlueprint>(false);
+ auto result = std::make_unique<SameElementBlueprint>("foo", false);
for (size_t i = 0; i < children.size(); ++i) {
uint32_t field_id = i;
vespalib::string field_name = vespalib::make_string("f%u", field_id);
diff --git a/searchlib/src/vespa/searchlib/common/struct_field_mapper.h b/searchlib/src/vespa/searchlib/common/struct_field_mapper.h
index 07951db99f7..1d0604daec3 100644
--- a/searchlib/src/vespa/searchlib/common/struct_field_mapper.h
+++ b/searchlib/src/vespa/searchlib/common/struct_field_mapper.h
@@ -22,6 +22,7 @@ private:
public:
StructFieldMapper();
~StructFieldMapper();
+ bool empty() const { return _struct_fields.empty(); }
void add_mapping(const vespalib::string &struct_field_name,
const vespalib::string &struct_subfield_name)
{
diff --git a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp
index 2376b129fc1..9b84136e67c 100644
--- a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.cpp
@@ -10,11 +10,12 @@
namespace search::queryeval {
-SameElementBlueprint::SameElementBlueprint(bool expensive)
+SameElementBlueprint::SameElementBlueprint(const vespalib::string &struct_field_name_in, bool expensive)
: ComplexLeafBlueprint(FieldSpecBaseList()),
_estimate(),
_layout(),
- _terms()
+ _terms(),
+ _struct_field_name(struct_field_name_in)
{
if (expensive) {
set_cost_tier(State::COST_TIER_EXPENSIVE);
@@ -60,13 +61,9 @@ SameElementBlueprint::fetchPostings(bool strict)
}
}
-SearchIterator::UP
-SameElementBlueprint::createLeafSearch(const search::fef::TermFieldMatchDataArray &tfmda,
- bool strict) const
+std::unique_ptr<SameElementSearch>
+SameElementBlueprint::create_same_element_search(bool strict) const
{
- (void) tfmda;
- assert(!tfmda.valid());
-
fef::MatchDataLayout my_layout = _layout;
std::vector<fef::TermFieldHandle> extra_handles;
for (size_t i = 0; i < _terms.size(); ++i) {
@@ -93,6 +90,15 @@ SameElementBlueprint::createLeafSearch(const search::fef::TermFieldMatchDataArra
return std::make_unique<SameElementSearch>(std::move(md), std::move(children), childMatch, strict);
}
+SearchIterator::UP
+SameElementBlueprint::createLeafSearch(const search::fef::TermFieldMatchDataArray &tfmda,
+ bool strict) const
+{
+ (void) tfmda;
+ assert(!tfmda.valid());
+ return create_same_element_search(strict);
+}
+
void
SameElementBlueprint::visitMembers(vespalib::ObjectVisitor &visitor) const
{
diff --git a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h
index 3b29e518aa1..e6fe9f8929c 100644
--- a/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h
+++ b/searchlib/src/vespa/searchlib/queryeval/same_element_blueprint.h
@@ -9,15 +9,18 @@ namespace search::fef { class TermFieldMatchData; }
namespace search::queryeval {
+class SameElementSearch;
+
class SameElementBlueprint : public ComplexLeafBlueprint
{
private:
HitEstimate _estimate;
fef::MatchDataLayout _layout;
std::vector<Blueprint::UP> _terms;
+ vespalib::string _struct_field_name;
public:
- SameElementBlueprint(bool expensive);
+ SameElementBlueprint(const vespalib::string &struct_field_name_in, bool expensive);
SameElementBlueprint(const SameElementBlueprint &) = delete;
SameElementBlueprint &operator=(const SameElementBlueprint &) = delete;
~SameElementBlueprint();
@@ -34,10 +37,12 @@ public:
void optimize_self() override;
void fetchPostings(bool strict) override;
+ std::unique_ptr<SameElementSearch> create_same_element_search(bool strict) const;
SearchIteratorUP createLeafSearch(const search::fef::TermFieldMatchDataArray &tfmda,
bool strict) const override;
void visitMembers(vespalib::ObjectVisitor &visitor) const override;
const std::vector<Blueprint::UP> &terms() const { return _terms; }
+ const vespalib::string &struct_field_name() const { return _struct_field_name; }
};
}