summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorArne Juul <arnej@verizonmedia.com>2020-07-09 14:24:17 +0000
committerArne Juul <arnej@verizonmedia.com>2020-07-15 15:39:21 +0000
commit37a48bad66fc204941499981d323ae9e86074ab6 (patch)
tree8b306a5791575f888693d04b243952ba8d1a706c /searchlib
parente32a939c6fc814bda36d2b104546e8c3d5d8e9d4 (diff)
support multiple positions in query
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/vespa/searchlib/features/distancefeature.cpp76
-rw-r--r--searchlib/src/vespa/searchlib/features/distancefeature.h7
-rw-r--r--searchlib/src/vespa/searchlib/fef/iqueryenvironment.h6
-rw-r--r--searchlib/src/vespa/searchlib/fef/phrase_splitter_query_env.h5
-rw-r--r--searchlib/src/vespa/searchlib/fef/test/queryenvironment.h7
5 files changed, 65 insertions, 36 deletions
diff --git a/searchlib/src/vespa/searchlib/features/distancefeature.cpp b/searchlib/src/vespa/searchlib/features/distancefeature.cpp
index 7a624e64d67..1c40399892c 100644
--- a/searchlib/src/vespa/searchlib/features/distancefeature.cpp
+++ b/searchlib/src/vespa/searchlib/features/distancefeature.cpp
@@ -82,7 +82,7 @@ ConvertRawscoreToDistance::execute(uint32_t docId)
feature_t
DistanceExecutor::calculateDistance(uint32_t docId)
{
- if (_location.isValid() && _pos != nullptr) {
+ if ((! _locations.empty()) && _pos != nullptr) {
return calculate2DZDistance(docId);
}
return DEFAULT_DISTANCE;
@@ -97,35 +97,32 @@ DistanceExecutor::calculate2DZDistance(uint32_t docId)
uint64_t sqabsdist = std::numeric_limits<uint64_t>::max();
int32_t docx = 0;
int32_t docy = 0;
- for (uint32_t i = 0; i < numValues; ++i) {
- vespalib::geo::ZCurve::decode(_intBuf[i], &docx, &docy);
- uint32_t dx;
- uint32_t dy;
- if (_location.getXPosition() > docx) {
- dx = _location.getXPosition() - docx;
- } else {
- dx = docx - _location.getXPosition();
- }
- if (_location.getXAspect() != 0) {
- dx = ((uint64_t) dx * _location.getXAspect()) >> 32;
- }
- if (_location.getYPosition() > docy) {
- dy = _location.getYPosition() - docy;
- } else {
- dy = docy - _location.getYPosition();
- }
- uint64_t sqdist = (uint64_t) dx * dx + (uint64_t) dy * dy;
- if (sqdist < sqabsdist) {
- sqabsdist = sqdist;
+ for (auto loc : _locations) {
+ assert(loc);
+ assert(loc->isValid());
+ int32_t loc_x = loc->getXPosition();
+ int32_t loc_y = loc->getYPosition();
+ uint64_t loc_a = loc->getXAspect();
+ for (uint32_t i = 0; i < numValues; ++i) {
+ vespalib::geo::ZCurve::decode(_intBuf[i], &docx, &docy);
+ uint32_t dx = (loc_x > docx) ? (loc_x - docx) : (docx - loc_x);
+ if (loc_a != 0) {
+ dx = (uint64_t(dx) * loc_a) >> 32;
+ }
+ uint32_t dy = (loc_y > docy) ? (loc_y - docy) : (docy - loc_y);
+ uint64_t sqdist = (uint64_t) dx * dx + (uint64_t) dy * dy;
+ if (sqdist < sqabsdist) {
+ sqabsdist = sqdist;
+ }
}
}
return static_cast<feature_t>(std::sqrt(static_cast<feature_t>(sqabsdist)));
}
-DistanceExecutor::DistanceExecutor(const Location & location,
+DistanceExecutor::DistanceExecutor(std::vector<const Location *> locations,
const search::attribute::IAttributeVector * pos) :
FeatureExecutor(),
- _location(location),
+ _locations(locations),
_pos(pos),
_intBuf()
{
@@ -231,6 +228,7 @@ DistanceBlueprint::setup(const IIndexEnvironment & env,
return setup_geopos(env, z);
}
if (allow_bad_field) {
+ // TODO remove on Vespa 8
// backwards compatibility fallback:
return setup_geopos(env, arg);
}
@@ -251,11 +249,31 @@ DistanceBlueprint::createExecutor(const IQueryEnvironment &env, vespalib::Stash
if (_use_item_label) {
return stash.create<ConvertRawscoreToDistance>(env, _arg_string);
}
- const search::attribute::IAttributeVector * pos = nullptr;
- const Location & location = env.getLocation();
+ std::vector<const search::fef::Location *> matching_locs;
+ std::vector<const search::fef::Location *> other_locs;
+
+ for (auto loc_ptr : env.getAllLocations()) {
+ if (_use_geo_pos && loc_ptr && loc_ptr->isValid()) {
+ if (loc_ptr->getAttribute() == _arg_string) {
+ LOG(info, "found loc from query env matching '%s'", _arg_string.c_str());
+ matching_locs.push_back(loc_ptr);
+ } else {
+ LOG(info, "found loc(%s) from query env not matching arg(%s)",
+ loc_ptr->getAttribute().c_str(), _arg_string.c_str());
+ other_locs.push_back(loc_ptr);
+ }
+ }
+ }
+ if (matching_locs.empty() && other_locs.empty()) {
+ LOG(debug, "DistanceBlueprint::createExecutor no valid locations");
+ return stash.create<DistanceExecutor>(matching_locs, nullptr);
+ }
LOG(debug, "DistanceBlueprint::createExecutor location.valid='%s', attribute='%s'",
- location.isValid() ? "true" : "false", _arg_string.c_str());
- if (_use_geo_pos && location.isValid()) {
+ "true", _arg_string.c_str());
+
+ const search::attribute::IAttributeVector * pos = nullptr;
+
+ if (_use_geo_pos) {
pos = env.getAttributeContext().getAttribute(_arg_string);
if (pos != nullptr) {
if (!pos->isIntegerType()) {
@@ -271,8 +289,8 @@ DistanceBlueprint::createExecutor(const IQueryEnvironment &env, vespalib::Stash
LOG(warning, "The position attribute '%s' was not found. Will use default distance.", _arg_string.c_str());
}
}
-
- return stash.create<DistanceExecutor>(location, pos);
+ return stash.create<DistanceExecutor>(matching_locs.empty() ? other_locs : matching_locs,
+ pos);
}
}
diff --git a/searchlib/src/vespa/searchlib/features/distancefeature.h b/searchlib/src/vespa/searchlib/features/distancefeature.h
index 3a8edd5ee94..024b9f37f31 100644
--- a/searchlib/src/vespa/searchlib/features/distancefeature.h
+++ b/searchlib/src/vespa/searchlib/features/distancefeature.h
@@ -12,7 +12,7 @@ namespace search::features {
*/
class DistanceExecutor : public fef::FeatureExecutor {
private:
- const fef::Location & _location;
+ std::vector<const fef::Location *> _locations;
const attribute::IAttributeVector * _pos;
attribute::IntegerContent _intBuf;
@@ -23,10 +23,11 @@ public:
/**
* Constructs an executor for the distance feature.
*
- * @param location the location object associated with the query environment.
+ * @param locations location objects associated with the query environment.
* @param pos the attribute to use for positions (expects zcurve encoding).
*/
- DistanceExecutor(const fef::Location & location, const attribute::IAttributeVector * pos);
+ DistanceExecutor(std::vector<const fef::Location *> locations,
+ const attribute::IAttributeVector * pos);
void execute(uint32_t docId) override;
static const feature_t DEFAULT_DISTANCE;
diff --git a/searchlib/src/vespa/searchlib/fef/iqueryenvironment.h b/searchlib/src/vespa/searchlib/fef/iqueryenvironment.h
index 041e9ec67bc..1aad1c7c034 100644
--- a/searchlib/src/vespa/searchlib/fef/iqueryenvironment.h
+++ b/searchlib/src/vespa/searchlib/fef/iqueryenvironment.h
@@ -58,9 +58,11 @@ public:
/**
* Obtain the location information associated with this query environment.
*
- * @return location object.
+ * @return location objects.
**/
- virtual const Location & getLocation() const = 0;
+ // virtual const Location & getLocation() const = 0;
+
+ virtual std::vector<const Location *> getAllLocations() const = 0;
/**
* Returns the attribute context for this query.
diff --git a/searchlib/src/vespa/searchlib/fef/phrase_splitter_query_env.h b/searchlib/src/vespa/searchlib/fef/phrase_splitter_query_env.h
index b2a3d416f5a..995fe25d000 100644
--- a/searchlib/src/vespa/searchlib/fef/phrase_splitter_query_env.h
+++ b/searchlib/src/vespa/searchlib/fef/phrase_splitter_query_env.h
@@ -73,7 +73,10 @@ public:
}
const Properties & getProperties() const override { return _queryEnv.getProperties(); }
- const Location & getLocation() const override { return _queryEnv.getLocation(); }
+ // const Location & getLocation() const override { return _queryEnv.getLocation(); }
+ std::vector<const Location *> getAllLocations() const override {
+ return _queryEnv.getAllLocations();
+ }
const attribute::IAttributeContext & getAttributeContext() const override { return _queryEnv.getAttributeContext(); }
double get_average_field_length(const vespalib::string &field_name) const override { return _queryEnv.get_average_field_length(field_name); }
const IIndexEnvironment & getIndexEnvironment() const override { return _queryEnv.getIndexEnvironment(); }
diff --git a/searchlib/src/vespa/searchlib/fef/test/queryenvironment.h b/searchlib/src/vespa/searchlib/fef/test/queryenvironment.h
index 40898281794..c04cf6da995 100644
--- a/searchlib/src/vespa/searchlib/fef/test/queryenvironment.h
+++ b/searchlib/src/vespa/searchlib/fef/test/queryenvironment.h
@@ -38,7 +38,12 @@ public:
const Properties &getProperties() const override { return _properties; }
uint32_t getNumTerms() const override { return _terms.size(); }
const ITermData *getTerm(uint32_t idx) const override { return idx < _terms.size() ? &_terms[idx] : NULL; }
- const Location & getLocation() const override { return _location; }
+ // const Location & getLocation() const override { return _location; }
+ std::vector<const Location *> getAllLocations() const override {
+ std::vector<const Location *> retval;
+ retval.push_back(&_location);
+ return retval;
+ }
const search::attribute::IAttributeContext &getAttributeContext() const override { return *_attrCtx; }
double get_average_field_length(const vespalib::string& field_name) const override {
auto itr = _avg_field_lengths.find(field_name);