aboutsummaryrefslogtreecommitdiffstats
path: root/searchsummary
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@oath.com>2018-06-08 13:19:41 +0000
committerTor Egge <Tor.Egge@oath.com>2018-06-08 13:19:41 +0000
commita458fe4166457b9205fe1ff21ceca3af558eb303 (patch)
treec30228f3bea83332ceeed8eb5fb7528caf65019b /searchsummary
parent7199422d00d1256cd7e0e09060bdf94c425400ac (diff)
Add docsum field writer for map of struct based on values in struct
field attributes.
Diffstat (limited to 'searchsummary')
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/CMakeLists.txt1
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.cpp4
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/struct_map_attribute_combiner_dfw.cpp116
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/struct_map_attribute_combiner_dfw.h30
4 files changed, 149 insertions, 2 deletions
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/CMakeLists.txt b/searchsummary/src/vespa/searchsummary/docsummary/CMakeLists.txt
index ce54e7b0ea7..dccf72b2fe7 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/CMakeLists.txt
+++ b/searchsummary/src/vespa/searchsummary/docsummary/CMakeLists.txt
@@ -25,6 +25,7 @@ vespa_add_library(searchsummary_docsummary OBJECT
positionsdfw.cpp
linguisticsannotation.cpp
searchdatatype.cpp
+ struct_map_attribute_combiner_dfw.cpp
summaryfieldconverter.cpp
AFTER
searchsummary_config
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.cpp
index b532cfb273a..e72caf9405b 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.cpp
+++ b/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.cpp
@@ -2,6 +2,7 @@
#include "attribute_combiner_dfw.h"
#include "array_attribute_combiner_dfw.h"
+#include "struct_map_attribute_combiner_dfw.h"
#include "docsum_field_writer_state.h"
#include "docsumstate.h"
#include <vespa/searchlib/attribute/attributeguard.h>
@@ -117,8 +118,7 @@ AttributeCombinerDFW::create(const vespalib::string &fieldName, IAttributeManage
if (structFields.getError()) {
return std::unique_ptr<IDocsumFieldWriter>();
} else if (!structFields.getMapFields().empty()) {
- LOG(warning, "map of struct is not yet supported for field '%s'", fieldName.c_str());
- return std::unique_ptr<IDocsumFieldWriter>();
+ return std::make_unique<StructMapAttributeCombinerDFW>(fieldName, structFields.getMapFields());
}
return std::make_unique<ArrayAttributeCombinerDFW>(fieldName, structFields.getArrayFields());
}
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/struct_map_attribute_combiner_dfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/struct_map_attribute_combiner_dfw.cpp
new file mode 100644
index 00000000000..3395727b290
--- /dev/null
+++ b/searchsummary/src/vespa/searchsummary/docsummary/struct_map_attribute_combiner_dfw.cpp
@@ -0,0 +1,116 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "struct_map_attribute_combiner_dfw.h"
+#include "docsum_field_writer_state.h"
+#include "attribute_field_writer.h"
+#include <vespa/searchcommon/attribute/iattributecontext.h>
+#include <vespa/searchcommon/attribute/iattributevector.h>
+#include <vespa/vespalib/data/slime/cursor.h>
+
+using search::attribute::IAttributeContext;
+using search::attribute::IAttributeVector;
+using vespalib::slime::Cursor;
+
+namespace search::docsummary {
+
+namespace {
+
+vespalib::Memory keyName("key");
+vespalib::Memory valueName("value");
+
+class StructMapAttributeFieldWriterState : public DocsumFieldWriterState
+{
+ std::unique_ptr<AttributeFieldWriter> _keyWriter;
+ std::vector<std::unique_ptr<AttributeFieldWriter>> _writers;
+
+public:
+ StructMapAttributeFieldWriterState(const vespalib::string &keyAttributeName,
+ const std::vector<vespalib::string> &fieldNames,
+ const std::vector<vespalib::string> &attributeNames,
+ IAttributeContext &context);
+ ~StructMapAttributeFieldWriterState() override;
+ void insertField(uint32_t docId, vespalib::slime::Inserter &target) override;
+};
+
+StructMapAttributeFieldWriterState::StructMapAttributeFieldWriterState(const vespalib::string &keyAttributeName,
+ const std::vector<vespalib::string> &fieldNames,
+ const std::vector<vespalib::string> &attributeNames,
+ IAttributeContext &context)
+ : DocsumFieldWriterState(),
+ _keyWriter(),
+ _writers()
+{
+ const IAttributeVector *attr = context.getAttribute(keyAttributeName);
+ if (attr != nullptr) {
+ _keyWriter = AttributeFieldWriter::create(keyName, *attr);
+ }
+ size_t fields = fieldNames.size();
+ _writers.reserve(fields);
+ for (uint32_t field = 0; field < fields; ++field) {
+ attr = context.getAttribute(attributeNames[field]);
+ if (attr != nullptr) {
+ _writers.emplace_back(AttributeFieldWriter::create(fieldNames[field], *attr));
+ }
+ }
+}
+
+StructMapAttributeFieldWriterState::~StructMapAttributeFieldWriterState() = default;
+
+void
+StructMapAttributeFieldWriterState::insertField(uint32_t docId, vespalib::slime::Inserter &target)
+{
+ uint32_t elems = 0;
+ if (_keyWriter) {
+ _keyWriter->fetch(docId);
+ if (elems < _keyWriter->size()) {
+ elems = _keyWriter->size();
+ }
+ }
+ for (auto &writer : _writers) {
+ writer->fetch(docId);
+ if (elems < writer->size()) {
+ elems = writer->size();
+ }
+ }
+ if (elems == 0) {
+ return;
+ }
+ Cursor &arr = target.insertArray();
+ for (uint32_t idx = 0; idx < elems; ++idx) {
+ Cursor &keyValueObj = arr.addObject();
+ if (_keyWriter) {
+ _keyWriter->print(idx, keyValueObj);
+ }
+ Cursor &obj = keyValueObj.setObject(valueName);
+ for (auto &writer : _writers) {
+ writer->print(idx, obj);
+ }
+ }
+}
+
+}
+
+StructMapAttributeCombinerDFW::StructMapAttributeCombinerDFW(const vespalib::string &fieldName,
+ const std::vector<vespalib::string> &fields)
+ : AttributeCombinerDFW(fieldName),
+ _keyAttributeName(),
+ _fields(fields),
+ _attributeNames()
+{
+ _keyAttributeName = fieldName + ".key";
+ _attributeNames.reserve(_fields.size());
+ vespalib::string prefix = fieldName + ".value.";
+ for (const auto &field : _fields) {
+ _attributeNames.emplace_back(prefix + field);
+ }
+}
+
+StructMapAttributeCombinerDFW::~StructMapAttributeCombinerDFW() = default;
+
+std::unique_ptr<DocsumFieldWriterState>
+StructMapAttributeCombinerDFW::allocFieldWriterState(IAttributeContext &context)
+{
+ return std::make_unique<StructMapAttributeFieldWriterState>(_keyAttributeName, _fields, _attributeNames, context);
+}
+
+}
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/struct_map_attribute_combiner_dfw.h b/searchsummary/src/vespa/searchsummary/docsummary/struct_map_attribute_combiner_dfw.h
new file mode 100644
index 00000000000..553d82f6754
--- /dev/null
+++ b/searchsummary/src/vespa/searchsummary/docsummary/struct_map_attribute_combiner_dfw.h
@@ -0,0 +1,30 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include "attribute_combiner_dfw.h"
+
+namespace search::attribute { class IAttributeContext; }
+
+namespace search::docsummary {
+
+class DocsumFieldWriterState;
+
+/*
+ * This class reads values from multiple struct field attributes and
+ * inserts them as a map of struct.
+ */
+class StructMapAttributeCombinerDFW : public AttributeCombinerDFW
+{
+ vespalib::string _keyAttributeName;
+ std::vector<vespalib::string> _fields;
+ std::vector<vespalib::string> _attributeNames;
+
+ std::unique_ptr<DocsumFieldWriterState> allocFieldWriterState(search::attribute::IAttributeContext &context) override;
+public:
+ StructMapAttributeCombinerDFW(const vespalib::string &fieldName,
+ const std::vector<vespalib::string> &fields);
+ ~StructMapAttributeCombinerDFW() override;
+};
+
+}