From 2062751bf548d9df60aa831bb402dcfb176cdc1d Mon Sep 17 00:00:00 2001 From: Arne H Juul Date: Fri, 28 Jan 2022 11:26:49 +0000 Subject: add GeoPosFieldSearcher --- vsm/src/vespa/vsm/searcher/CMakeLists.txt | 1 + vsm/src/vespa/vsm/searcher/fieldsearcher.cpp | 1 + vsm/src/vespa/vsm/searcher/fieldsearcher.h | 1 + .../vespa/vsm/searcher/geo_pos_field_searcher.cpp | 78 ++++++++++++++++++++++ .../vespa/vsm/searcher/geo_pos_field_searcher.h | 28 ++++++++ 5 files changed, 109 insertions(+) create mode 100644 vsm/src/vespa/vsm/searcher/geo_pos_field_searcher.cpp create mode 100644 vsm/src/vespa/vsm/searcher/geo_pos_field_searcher.h (limited to 'vsm') diff --git a/vsm/src/vespa/vsm/searcher/CMakeLists.txt b/vsm/src/vespa/vsm/searcher/CMakeLists.txt index 0fab39c5586..0a2a9ec21d2 100644 --- a/vsm/src/vespa/vsm/searcher/CMakeLists.txt +++ b/vsm/src/vespa/vsm/searcher/CMakeLists.txt @@ -13,6 +13,7 @@ vespa_add_library(vsm_vsmsearcher OBJECT floatfieldsearcher.cpp ${SSE2_FILES} futf8strchrfieldsearcher.cpp + geo_pos_field_searcher.cpp intfieldsearcher.cpp strchrfieldsearcher.cpp utf8flexiblestringfieldsearcher.cpp diff --git a/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp b/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp index b48c5e7d493..c587f9eadfb 100644 --- a/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp +++ b/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp @@ -295,6 +295,7 @@ void FieldSearcher::IteratorHandler::onStructStart(const Content & c) { LOG(spam, "onStructStart: field value '%s'", c.getValue().toString().c_str()); + _searcher.onStructValue(static_cast(c.getValue())); } diff --git a/vsm/src/vespa/vsm/searcher/fieldsearcher.h b/vsm/src/vespa/vsm/searcher/fieldsearcher.h index eb1f3ddd524..5c2ef8fec28 100644 --- a/vsm/src/vespa/vsm/searcher/fieldsearcher.h +++ b/vsm/src/vespa/vsm/searcher/fieldsearcher.h @@ -99,6 +99,7 @@ private: void setCurrentElementId(int32_t weight) { _currentElementId = weight; } bool onSearch(const StorageDocument & doc); virtual void onValue(const document::FieldValue & fv) = 0; + virtual void onStructValue(const document::StructFieldValue &) { } FieldIdT _field; MatchType _matchType; unsigned _maxFieldLength; diff --git a/vsm/src/vespa/vsm/searcher/geo_pos_field_searcher.cpp b/vsm/src/vespa/vsm/searcher/geo_pos_field_searcher.cpp new file mode 100644 index 00000000000..db93bda7778 --- /dev/null +++ b/vsm/src/vespa/vsm/searcher/geo_pos_field_searcher.cpp @@ -0,0 +1,78 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "geo_pos_field_searcher.h" +#include +#include +#include +#include +#include + +#include +LOG_SETUP(".vsm.searcher.geo_pos_field_searcher"); + +using search::streaming::QueryTerm; +using search::streaming::QueryTermList; +using search::common::GeoLocation; +using search::common::GeoLocationParser; + +namespace vsm { + +std::unique_ptr GeoPosFieldSearcher::duplicate() const { + return std::make_unique(*this); +} + +GeoPosFieldSearcher::GeoPosFieldSearcher(FieldIdT fId) : + FieldSearcher(fId), + _geoPosTerm() +{} + +GeoPosFieldSearcher::~GeoPosFieldSearcher() {} + +void GeoPosFieldSearcher::prepare(QueryTermList & qtl, const SharedSearcherBuf & buf) { + _geoPosTerm.clear(); + FieldSearcher::prepare(qtl, buf); + for (const QueryTerm * qt : qtl) { + const vespalib::string & str = qt->getTermString(); + GeoLocationParser parser; + bool valid = parser.parseNoField(str); + if (! valid) { + vespalib::Issue::report("invalid position in term: %s", str.c_str()); + } + _geoPosTerm.emplace_back(parser.getGeoLocation()); + } +} + +void GeoPosFieldSearcher::onValue(const document::FieldValue & fv) { + LOG(spam, "ignore field value '%s'", fv.toString().c_str()); +} + +void GeoPosFieldSearcher::onStructValue(const document::StructFieldValue & fv) { + size_t num_terms = _geoPosTerm.size(); + for (size_t j = 0; j < num_terms; ++j) { + const GeoPosInfo & gpi = _geoPosTerm[j]; + if (gpi.valid() && gpi.cmp(fv)) { + addHit(*_qtl[j], 0); + } + } + ++_words; +} + +bool GeoPosFieldSearcher::GeoPosInfo::cmp(const document::StructFieldValue & sfv) const { + try { + auto xv = sfv.getValue("x"); + auto yv = sfv.getValue("y"); + if (xv && yv) { + int32_t x = xv->getAsInt(); + int32_t y = yv->getAsInt(); + GeoLocation::Point p{x,y}; + if (inside_limit(p)) { + return true; + } + } + } catch (const vespalib::Exception &e) { + vespalib::Issue::report("bad fieldvalue for GeoPosFieldSearcher: %s", e.getMessage().c_str()); + } + return false; +} + +} diff --git a/vsm/src/vespa/vsm/searcher/geo_pos_field_searcher.h b/vsm/src/vespa/vsm/searcher/geo_pos_field_searcher.h new file mode 100644 index 00000000000..ef1c5b5a1c4 --- /dev/null +++ b/vsm/src/vespa/vsm/searcher/geo_pos_field_searcher.h @@ -0,0 +1,28 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#pragma once + +#include "fieldsearcher.h" +#include + +namespace vsm { + +class GeoPosFieldSearcher : public FieldSearcher { +public: + GeoPosFieldSearcher(FieldIdT fId=0); + ~GeoPosFieldSearcher(); + void prepare(search::streaming::QueryTermList & qtl, const SharedSearcherBuf & buf) override; + void onValue(const document::FieldValue & fv) override; + void onStructValue(const document::StructFieldValue & fv) override; + std::unique_ptr duplicate() const override; +protected: + using GeoLocation = search::common::GeoLocation; + class GeoPosInfo : public GeoLocation { + public: + GeoPosInfo (GeoLocation loc) noexcept : GeoLocation(std::move(loc)) {} + bool cmp(const document::StructFieldValue & fv) const; + }; + typedef std::vector GeoPosInfoListT; + GeoPosInfoListT _geoPosTerm; +}; + +} -- cgit v1.2.3