summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2018-06-13 13:57:13 +0000
committerHåvard Pettersen <havardpe@oath.com>2018-06-13 14:02:25 +0000
commit7aa433adafa69a27c8b864c77e21c35402891215 (patch)
tree4f6c199e81122a691e56baad744b2264a80edadc /searchlib
parent0fefd4e3b3038db6b3b2f573571034d3614816bf (diff)
enable native dot product to include all fields
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/features/native_dot_product/native_dot_product_test.cpp21
-rw-r--r--searchlib/src/vespa/searchlib/features/native_dot_product_feature.cpp29
-rw-r--r--searchlib/src/vespa/searchlib/features/native_dot_product_feature.h5
-rw-r--r--searchlib/src/vespa/searchlib/fef/featurenamebuilder.cpp2
4 files changed, 48 insertions, 9 deletions
diff --git a/searchlib/src/tests/features/native_dot_product/native_dot_product_test.cpp b/searchlib/src/tests/features/native_dot_product/native_dot_product_test.cpp
index 1da912ccb3a..0cf13443142 100644
--- a/searchlib/src/tests/features/native_dot_product/native_dot_product_test.cpp
+++ b/searchlib/src/tests/features/native_dot_product/native_dot_product_test.cpp
@@ -16,7 +16,8 @@ using namespace search::fef::test;
using namespace search::features;
using CollectionType = FieldInfo::CollectionType;
-const std::string featureName("nativeDotProduct(foo)");
+const std::string fooFeatureName("nativeDotProduct(foo)");
+const std::string anyFeatureName("nativeDotProduct");
struct BlueprintFactoryFixture {
BlueprintFactory factory;
@@ -78,7 +79,8 @@ struct RankFixture : BlueprintFactoryFixture, IndexFixture {
std::vector<TermFieldHandle> fooHandles;
std::vector<TermFieldHandle> barHandles;
RankFixture(const std::vector<uint32_t> &fooWeights,
- const std::vector<uint32_t> &barWeights)
+ const std::vector<uint32_t> &barWeights,
+ const vespalib::string &featureName = fooFeatureName)
: queryEnv(&indexEnv), rankSetup(factory, indexEnv),
mdl(), match_data(), rankProgram(), fooHandles(), barHandles()
{
@@ -152,6 +154,12 @@ TEST_FF("require that setup fails for unknown field", NativeDotProductBlueprint,
EXPECT_TRUE(!((Blueprint&)f1).setup(f2.indexEnv, std::vector<vespalib::string>(1, "unknown")));
}
+TEST_FF("require that setup can be done without field", NativeDotProductBlueprint, IndexFixture) {
+ DummyDependencyHandler deps(f1);
+ f1.setName(vespalib::make_string("%s", f1.getBaseName().c_str()));
+ EXPECT_TRUE(((Blueprint&)f1).setup(f2.indexEnv, std::vector<vespalib::string>()));
+}
+
TEST_F("require that not searching a field will give it 0.0 dot product", RankFixture(vec(), vec(1, 2, 3))) {
EXPECT_EQUAL(0.0, f1.getScore(10));
}
@@ -183,11 +191,18 @@ TEST_F("require that data from other fields is ignored", RankFixture(vec(1, 3),
EXPECT_EQUAL(14, f1.getScore(10));
}
+TEST_F("require that not specifying field includes all term/field combinations", RankFixture(vec(1, 3), vec(5, 7), anyFeatureName)) {
+ f1.setFooWeight(0, 10, 2);
+ f1.setFooWeight(1, 10, 4);
+ f1.setBarWeight(0, 10, 6);
+ f1.setBarWeight(1, 10, 8);
+ EXPECT_EQUAL(100, f1.getScore(10));
+}
+
TEST_F("require that negative weights in the index works", RankFixture(vec(1, 3), vec())) {
f1.setFooWeight(0, 10, 2);
f1.setFooWeight(1, 10, -4);
EXPECT_EQUAL(-10, f1.getScore(10));
}
-
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchlib/src/vespa/searchlib/features/native_dot_product_feature.cpp b/searchlib/src/vespa/searchlib/features/native_dot_product_feature.cpp
index cb8136e8b7f..7865e32849f 100644
--- a/searchlib/src/vespa/searchlib/features/native_dot_product_feature.cpp
+++ b/searchlib/src/vespa/searchlib/features/native_dot_product_feature.cpp
@@ -8,6 +8,23 @@ using namespace search::fef;
namespace search {
namespace features {
+NativeDotProductExecutor::NativeDotProductExecutor(const search::fef::IQueryEnvironment &env)
+ : FeatureExecutor(),
+ _pairs(),
+ _md(nullptr)
+{
+ for (uint32_t i = 0; i < env.getNumTerms(); ++i) {
+ const search::fef::ITermData *td = env.getTerm(i);
+ auto weight = td->getWeight();
+ for (size_t f = 0; f < td->numFields(); ++f) {
+ auto handle = td->field(f).getHandle();
+ if (handle != search::fef::IllegalHandle) {
+ _pairs.emplace_back(handle, weight);
+ }
+ }
+ }
+}
+
NativeDotProductExecutor::NativeDotProductExecutor(const search::fef::IQueryEnvironment &env, uint32_t fieldId)
: FeatureExecutor(),
_pairs(),
@@ -46,15 +63,21 @@ bool
NativeDotProductBlueprint::setup(const IIndexEnvironment &,
const ParameterList &params)
{
- _field = params[0].asField();
- describeOutput("out", "dot product between query term weights and match weights for the given field");
+ if (params.size() > 0) {
+ _field = params[0].asField();
+ }
+ describeOutput("out", "dot product between query term weights and match weights");
return true;
}
FeatureExecutor &
NativeDotProductBlueprint::createExecutor(const IQueryEnvironment &queryEnv, vespalib::Stash &stash) const
{
- return stash.create<NativeDotProductExecutor>(queryEnv, _field->id());
+ if (_field) {
+ return stash.create<NativeDotProductExecutor>(queryEnv, _field->id());
+ } else {
+ return stash.create<NativeDotProductExecutor>(queryEnv);
+ }
}
} // namespace features
diff --git a/searchlib/src/vespa/searchlib/features/native_dot_product_feature.h b/searchlib/src/vespa/searchlib/features/native_dot_product_feature.h
index a71d23f3158..33c5c89c88b 100644
--- a/searchlib/src/vespa/searchlib/features/native_dot_product_feature.h
+++ b/searchlib/src/vespa/searchlib/features/native_dot_product_feature.h
@@ -20,6 +20,7 @@ private:
void handle_bind_match_data(const fef::MatchData &md) override;
public:
+ NativeDotProductExecutor(const fef::IQueryEnvironment &env);
NativeDotProductExecutor(const fef::IQueryEnvironment &env, uint32_t fieldId);
void execute(uint32_t docId) override;
};
@@ -31,13 +32,13 @@ class NativeDotProductBlueprint : public fef::Blueprint
private:
const fef::FieldInfo *_field;
public:
- NativeDotProductBlueprint() : Blueprint("nativeDotProduct"), _field(0) {}
+ NativeDotProductBlueprint() : Blueprint("nativeDotProduct"), _field(nullptr) {}
void visitDumpFeatures(const fef::IIndexEnvironment &, fef::IDumpFeatureVisitor &) const override {}
fef::Blueprint::UP createInstance() const override {
return Blueprint::UP(new NativeDotProductBlueprint());
}
fef::ParameterDescriptions getDescriptions() const override {
- return fef::ParameterDescriptions().desc().field();
+ return fef::ParameterDescriptions().desc().field().desc();
}
bool setup(const fef::IIndexEnvironment &env, const fef::ParameterList &params) override;
fef::FeatureExecutor &createExecutor(const fef::IQueryEnvironment &env, vespalib::Stash &stash) const override;
diff --git a/searchlib/src/vespa/searchlib/fef/featurenamebuilder.cpp b/searchlib/src/vespa/searchlib/fef/featurenamebuilder.cpp
index ec00b7d2f90..0eba912fafd 100644
--- a/searchlib/src/vespa/searchlib/fef/featurenamebuilder.cpp
+++ b/searchlib/src/vespa/searchlib/fef/featurenamebuilder.cpp
@@ -136,7 +136,7 @@ FeatureNameBuilder::buildName() const
vespalib::string ret;
if (!_baseName.empty()) {
ret = _baseName;
- if (!_parameters.empty() > 0) {
+ if (!_parameters.empty()) {
ret += "(";
for (uint32_t i = 0; i < _parameters.size(); ++i) {
if (i > 0) {