diff options
author | Tor Egge <Tor.Egge@oath.com> | 2018-06-08 13:19:41 +0000 |
---|---|---|
committer | Tor Egge <Tor.Egge@oath.com> | 2018-06-08 13:19:41 +0000 |
commit | a458fe4166457b9205fe1ff21ceca3af558eb303 (patch) | |
tree | c30228f3bea83332ceeed8eb5fb7528caf65019b /searchsummary | |
parent | 7199422d00d1256cd7e0e09060bdf94c425400ac (diff) |
Add docsum field writer for map of struct based on values in struct
field attributes.
Diffstat (limited to 'searchsummary')
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; +}; + +} |