diff options
author | Arne Juul <arnej@verizonmedia.com> | 2020-07-09 14:24:17 +0000 |
---|---|---|
committer | Arne Juul <arnej@verizonmedia.com> | 2020-07-15 15:39:21 +0000 |
commit | 37a48bad66fc204941499981d323ae9e86074ab6 (patch) | |
tree | 8b306a5791575f888693d04b243952ba8d1a706c /searchlib | |
parent | e32a939c6fc814bda36d2b104546e8c3d5d8e9d4 (diff) |
support multiple positions in query
Diffstat (limited to 'searchlib')
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); |