summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@yahooinc.com>2023-04-28 14:37:03 +0200
committerGitHub <noreply@github.com>2023-04-28 14:37:03 +0200
commitc1fa64d3867c103047e9788545770e7524825e28 (patch)
tree1887017de5c8a48fbb271706f38bbe38c0b4d33f
parent3fdedbe3684fd4d924ec71ddc0f85428a57b898c (diff)
parent07f6d5be822832bb5c4bd31e0bdf23d0a8b5ac99 (diff)
Merge pull request #26903 from vespa-engine/geirst/streaming-search-match-features-test
Test match features returned in streaming search result.
-rwxr-xr-xstreamingvisitors/src/tests/searchvisitor/cfg/generate.sh3
-rw-r--r--streamingvisitors/src/tests/searchvisitor/cfg/rank-profiles.mycl.cfg24
-rw-r--r--streamingvisitors/src/tests/searchvisitor/cfg/summary.mycl.cfg16
-rw-r--r--streamingvisitors/src/tests/searchvisitor/cfg/test.sd11
-rw-r--r--streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp33
-rw-r--r--vespalib/src/vespa/vespalib/util/featureset.h5
6 files changed, 64 insertions, 28 deletions
diff --git a/streamingvisitors/src/tests/searchvisitor/cfg/generate.sh b/streamingvisitors/src/tests/searchvisitor/cfg/generate.sh
index 1eade461060..8a107453373 100755
--- a/streamingvisitors/src/tests/searchvisitor/cfg/generate.sh
+++ b/streamingvisitors/src/tests/searchvisitor/cfg/generate.sh
@@ -23,3 +23,6 @@ mv rank-profiles.cfg rank-profiles.mycl.cfg
mv summary.cfg summary.mycl.cfg
mv vsmfields.cfg vsmfields.mycl.cfg
mv vsmsummary.cfg vsmsummary.mycl.cfg
+
+# Add newline at eof
+for file in *.cfg; do echo >> $file; done
diff --git a/streamingvisitors/src/tests/searchvisitor/cfg/rank-profiles.mycl.cfg b/streamingvisitors/src/tests/searchvisitor/cfg/rank-profiles.mycl.cfg
index d3132a8ff25..be0f97b5276 100644
--- a/streamingvisitors/src/tests/searchvisitor/cfg/rank-profiles.mycl.cfg
+++ b/streamingvisitors/src/tests/searchvisitor/cfg/rank-profiles.mycl.cfg
@@ -1,4 +1,8 @@
rankprofile[0].name "default"
+rankprofile[0].fef.property[0].name "vespa.rank.firstphase"
+rankprofile[0].fef.property[0].value "rankingExpression(firstphase)"
+rankprofile[0].fef.property[1].name "rankingExpression(firstphase).rankingScript"
+rankprofile[0].fef.property[1].value "attribute(id) + 10"
rankprofile[1].name "unranked"
rankprofile[1].fef.property[0].name "vespa.rank.firstphase"
rankprofile[1].fef.property[0].value "value(0)"
@@ -8,8 +12,18 @@ rankprofile[1].fef.property[2].name "vespa.hitcollector.arraysize"
rankprofile[1].fef.property[2].value "0"
rankprofile[1].fef.property[3].name "vespa.dump.ignoredefaultfeatures"
rankprofile[1].fef.property[3].value "true"
-rankprofile[2].name "myrank"
-rankprofile[2].fef.property[0].name "vespa.rank.firstphase"
-rankprofile[2].fef.property[0].value "rankingExpression(firstphase)"
-rankprofile[2].fef.property[1].name "rankingExpression(firstphase).rankingScript"
-rankprofile[2].fef.property[1].value "attribute(id) + 10"
+rankprofile[2].name "match_features"
+rankprofile[2].fef.property[0].name "rankingExpression(myfunc).rankingScript"
+rankprofile[2].fef.property[0].value "attribute(id) + 20"
+rankprofile[2].fef.property[1].name "vespa.rank.firstphase"
+rankprofile[2].fef.property[1].value "rankingExpression(firstphase)"
+rankprofile[2].fef.property[2].name "rankingExpression(firstphase).rankingScript"
+rankprofile[2].fef.property[2].value "attribute(id) + 10"
+rankprofile[2].fef.property[3].name "vespa.match.feature"
+rankprofile[2].fef.property[3].value "attribute(id)"
+rankprofile[2].fef.property[4].name "vespa.match.feature"
+rankprofile[2].fef.property[4].value "rankingExpression(myfunc)"
+rankprofile[2].fef.property[5].name "vespa.feature.rename"
+rankprofile[2].fef.property[5].value "rankingExpression(myfunc)"
+rankprofile[2].fef.property[6].name "vespa.feature.rename"
+rankprofile[2].fef.property[6].value "myfunc"
diff --git a/streamingvisitors/src/tests/searchvisitor/cfg/summary.mycl.cfg b/streamingvisitors/src/tests/searchvisitor/cfg/summary.mycl.cfg
index 5983609ac9d..c67bcafddaa 100644
--- a/streamingvisitors/src/tests/searchvisitor/cfg/summary.mycl.cfg
+++ b/streamingvisitors/src/tests/searchvisitor/cfg/summary.mycl.cfg
@@ -15,8 +15,8 @@ classes[0].fields[2].source ""
classes[0].fields[3].name "documentid"
classes[0].fields[3].command "documentid"
classes[0].fields[3].source ""
-classes[1].id 1473683981
-classes[1].name "mysum"
+classes[1].id 1783786855
+classes[1].name "attributeprefetch"
classes[1].omitsummaryfeatures false
classes[1].fields[0].name "id"
classes[1].fields[0].command "attribute"
@@ -27,15 +27,3 @@ classes[1].fields[1].source ""
classes[1].fields[2].name "summaryfeatures"
classes[1].fields[2].command "summaryfeatures"
classes[1].fields[2].source ""
-classes[2].id 1783786855
-classes[2].name "attributeprefetch"
-classes[2].omitsummaryfeatures false
-classes[2].fields[0].name "id"
-classes[2].fields[0].command "attribute"
-classes[2].fields[0].source "id"
-classes[2].fields[1].name "rankfeatures"
-classes[2].fields[1].command "rankfeatures"
-classes[2].fields[1].source ""
-classes[2].fields[2].name "summaryfeatures"
-classes[2].fields[2].command "summaryfeatures"
-classes[2].fields[2].source ""
diff --git a/streamingvisitors/src/tests/searchvisitor/cfg/test.sd b/streamingvisitors/src/tests/searchvisitor/cfg/test.sd
index ad998aa91f6..ba2be3f1d93 100644
--- a/streamingvisitors/src/tests/searchvisitor/cfg/test.sd
+++ b/streamingvisitors/src/tests/searchvisitor/cfg/test.sd
@@ -4,13 +4,16 @@ schema test {
indexing: attribute | summary
}
}
- document-summary mysum {
- summary id type int {}
- }
- rank-profile myrank {
+ rank-profile default {
first-phase {
expression: attribute(id) + 10
}
}
+ rank-profile match_features inherits default {
+ function myfunc() {
+ expression: attribute(id) + 20
+ }
+ match-features: attribute(id) myfunc()
+ }
}
diff --git a/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp b/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp
index b93a2c25f82..0004e253aff 100644
--- a/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp
+++ b/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp
@@ -72,8 +72,8 @@ public:
RequestBuilder() : _params(), _builder(), _term_id(1)
{
search_cluster("mycl");
- rank_profile("myrank");
- summary_class("mysum");
+ rank_profile("default");
+ summary_class("default");
summary_count(10);
}
RequestBuilder& set_param(const vespalib::string& key, const vespalib::string& value) {
@@ -222,13 +222,36 @@ expect_summary(const HitVector& exp_summary, documentapi::QueryResultMessage& re
EXPECT_EQ(exp_summary, to_hit_vector(res.getDocumentSummary()));
}
+void
+expect_match_features(const std::vector<vespalib::string>& exp_names,
+ const std::vector<vespalib::FeatureSet::Value>& exp_values,
+ documentapi::QueryResultMessage& res)
+{
+ const auto& mf = res.getSearchResult().get_match_features();
+ EXPECT_EQ(exp_names, mf.names);
+ EXPECT_EQ(exp_values, mf.values);
+}
+
+
TEST_F(SearchVisitorTest, basic_query_execution_in_search_visitor)
{
- auto res = execute_query(RequestBuilder().
- number_term("[5;10]", "id").build(),
- {{3},{7},{4},{5},{9}});
+ auto res = execute_query(RequestBuilder().number_term("[5;10]", "id").build(),
+ {{3},{7},{4},{5},{9}});
expect_hits({{9,19.0}, {7,17.0}, {5,15.0}}, *res);
+ // Document summaries are ordered in document id order:
expect_summary({{5}, {7}, {9}}, *res);
+ expect_match_features({}, {}, *res);
+}
+
+TEST_F(SearchVisitorTest, match_features_returned_in_search_result)
+{
+ auto res = execute_query(RequestBuilder().
+ rank_profile("match_features").
+ number_term("[5;10]", "id").build(),
+ {{5},{4},{7}});
+ expect_hits({{7,17.0}, {5,15.0}}, *res);
+ // Raw match features are ordered in matching order.
+ expect_match_features({"attribute(id)", "myfunc"}, {{5.0}, {25.0}, {7.0}, {27.0}}, *res);
}
TEST_F(SearchVisitorTest, visitor_only_require_weak_read_consistency)
diff --git a/vespalib/src/vespa/vespalib/util/featureset.h b/vespalib/src/vespa/vespalib/util/featureset.h
index 5300b5faa86..79145a6eb71 100644
--- a/vespalib/src/vespa/vespalib/util/featureset.h
+++ b/vespalib/src/vespa/vespalib/util/featureset.h
@@ -27,6 +27,11 @@ public:
_value(0.0)
{
}
+ Value(double value_in) noexcept
+ : _data(),
+ _value(value_in)
+ {
+ }
bool operator==(const Value &rhs) const {
return ((_data == rhs._data) && (_value == rhs._value));
}