summaryrefslogtreecommitdiffstats
path: root/vsm
diff options
context:
space:
mode:
authorArne H Juul <arnej@yahooinc.com>2022-01-28 11:26:49 +0000
committerArne H Juul <arnej@yahooinc.com>2022-01-28 11:31:11 +0000
commit2062751bf548d9df60aa831bb402dcfb176cdc1d (patch)
tree54efdf20b08186ff5a1fd356158512b078491cde /vsm
parent30158a9d1d4f275ce087744e50f4049049afdb6d (diff)
add GeoPosFieldSearcher
Diffstat (limited to 'vsm')
-rw-r--r--vsm/src/vespa/vsm/searcher/CMakeLists.txt1
-rw-r--r--vsm/src/vespa/vsm/searcher/fieldsearcher.cpp1
-rw-r--r--vsm/src/vespa/vsm/searcher/fieldsearcher.h1
-rw-r--r--vsm/src/vespa/vsm/searcher/geo_pos_field_searcher.cpp78
-rw-r--r--vsm/src/vespa/vsm/searcher/geo_pos_field_searcher.h28
5 files changed, 109 insertions, 0 deletions
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<const document::StructFieldValue &>(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 <vespa/document/fieldvalue/arrayfieldvalue.h>
+#include <vespa/document/fieldvalue/structfieldvalue.h>
+#include <vespa/searchlib/common/geo_location_parser.h>
+#include <vespa/vespalib/util/issue.h>
+#include <vespa/vespalib/util/exception.h>
+
+#include <vespa/log/log.h>
+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<FieldSearcher> GeoPosFieldSearcher::duplicate() const {
+ return std::make_unique<GeoPosFieldSearcher>(*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 <vespa/searchlib/common/geo_location.h>
+
+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<FieldSearcher> 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<GeoPosInfo> GeoPosInfoListT;
+ GeoPosInfoListT _geoPosTerm;
+};
+
+}