summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArne H Juul <arnej27959@users.noreply.github.com>2022-01-19 09:54:55 +0100
committerGitHub <noreply@github.com>2022-01-19 09:54:55 +0100
commite79d967e99c27412e502d4aaa32b6a60d88fcbbb (patch)
treef9ec474e290bb9aec886f57ff8f538d0a87ead5c
parent4cc7565cfe27aef8809337f3d926dbfff18f3b9a (diff)
parent7572116c9c76967ec986803103bcbc3427083762 (diff)
Merge pull request #20861 from vespa-engine/arnej/special-document-only-fieldset
add special '[document]' fieldset
-rw-r--r--document/src/vespa/document/base/field.cpp1
-rw-r--r--document/src/vespa/document/datatype/documenttype.cpp24
-rw-r--r--document/src/vespa/document/datatype/documenttype.h15
-rw-r--r--document/src/vespa/document/fieldset/fieldset.h3
-rw-r--r--document/src/vespa/document/fieldset/fieldsetrepo.cpp6
-rw-r--r--document/src/vespa/document/fieldset/fieldsets.cpp16
-rw-r--r--document/src/vespa/document/fieldset/fieldsets.h12
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentretriever.cpp9
8 files changed, 74 insertions, 12 deletions
diff --git a/document/src/vespa/document/base/field.cpp b/document/src/vespa/document/base/field.cpp
index 5c696d80fe7..86b1d93eacf 100644
--- a/document/src/vespa/document/base/field.cpp
+++ b/document/src/vespa/document/base/field.cpp
@@ -79,6 +79,7 @@ Field::contains(const FieldSet& fields) const
case Type::NONE:
case Type::DOCID:
return true;
+ case Type::DOCUMENT_ONLY:
case Type::ALL:
return false;
}
diff --git a/document/src/vespa/document/datatype/documenttype.cpp b/document/src/vespa/document/datatype/documenttype.cpp
index 81389d25bd7..1c43e2dfc64 100644
--- a/document/src/vespa/document/datatype/documenttype.cpp
+++ b/document/src/vespa/document/datatype/documenttype.cpp
@@ -14,8 +14,30 @@ using vespalib::IllegalArgumentException;
using vespalib::make_string;
using vespalib::stringref;
+
namespace document {
+namespace {
+FieldCollection build_field_collection(const std::set<vespalib::string> &fields,
+ const DocumentType &doc_type)
+{
+ Field::Set::Builder builder;
+ for (const auto & field_name : fields) {
+ if (doc_type.hasField(field_name)) {
+ builder.add(&doc_type.getField(field_name));
+ }
+ }
+ return FieldCollection(doc_type, builder.build());
+}
+} // namespace <unnamed>
+
+DocumentType::FieldSet::FieldSet(const vespalib::string & name, Fields fields,
+ const DocumentType & doc_type)
+ : _name(name),
+ _fields(fields),
+ _field_collection(build_field_collection(fields, doc_type))
+{}
+
IMPLEMENT_IDENTIFIABLE(DocumentType, StructuredDataType);
DocumentType::DocumentType() = default;
@@ -75,7 +97,7 @@ DocumentType::~DocumentType() = default;
DocumentType &
DocumentType::addFieldSet(const vespalib::string & name, FieldSet::Fields fields)
{
- _fieldSets[name] = FieldSet(name, std::move(fields));
+ _fieldSets.emplace(name, FieldSet(name, std::move(fields), *this));
return *this;
}
diff --git a/document/src/vespa/document/datatype/documenttype.h b/document/src/vespa/document/datatype/documenttype.h
index 28a0f0c9d55..bddc0a26e99 100644
--- a/document/src/vespa/document/datatype/documenttype.h
+++ b/document/src/vespa/document/datatype/documenttype.h
@@ -11,6 +11,7 @@
#pragma once
+#include <vespa/document/fieldset/fieldsets.h>
#include <vespa/document/datatype/structdatatype.h>
#include <vespa/vespalib/stllike/hash_set.h>
#include <vespa/vespalib/stllike/string.h>
@@ -28,23 +29,19 @@ public:
class FieldSet {
public:
using Fields = std::set<vespalib::string>;
- FieldSet() = default;
- explicit FieldSet(const vespalib::string & name) : _name(name), _fields() {}
- FieldSet(const vespalib::string & name, Fields fields) : _name(name), _fields(std::move(fields)) {}
+ FieldSet(const vespalib::string & name, Fields fields,
+ const DocumentType & doc_type);
+
FieldSet(const FieldSet&) = default;
- FieldSet& operator=(const FieldSet&) = default;
FieldSet(FieldSet&&) noexcept = default;
- FieldSet& operator=(FieldSet&&) noexcept = default;
const vespalib::string & getName() const noexcept { return _name; }
const Fields & getFields() const noexcept { return _fields; }
- FieldSet & add(vespalib::string & field) {
- _fields.insert(field);
- return *this;
- }
+ const FieldCollection & asCollection() const { return _field_collection; }
private:
vespalib::string _name;
Fields _fields;
+ FieldCollection _field_collection;
};
using FieldSetMap = std::map<vespalib::string, FieldSet>;
using ImportedFieldNames = vespalib::hash_set<vespalib::string>;
diff --git a/document/src/vespa/document/fieldset/fieldset.h b/document/src/vespa/document/fieldset/fieldset.h
index fd604a19e08..1f53f7a3456 100644
--- a/document/src/vespa/document/fieldset/fieldset.h
+++ b/document/src/vespa/document/fieldset/fieldset.h
@@ -20,7 +20,8 @@ public:
SET,
ALL,
NONE,
- DOCID
+ DOCID,
+ DOCUMENT_ONLY
};
using SP = std::shared_ptr<FieldSet>;
diff --git a/document/src/vespa/document/fieldset/fieldsetrepo.cpp b/document/src/vespa/document/fieldset/fieldsetrepo.cpp
index 97b7fa09813..851eb8f4ecf 100644
--- a/document/src/vespa/document/fieldset/fieldsetrepo.cpp
+++ b/document/src/vespa/document/fieldset/fieldsetrepo.cpp
@@ -28,10 +28,12 @@ parseSpecialValues(vespalib::stringref name)
return std::make_shared<NoFields>();
} else if ((name.size() == 7) && (name[1] == 'd') && (name[2] == 'o') && (name[3] == 'c') && (name[4] == 'i') && (name[5] == 'd') && (name[6] == ']')) {
return std::make_shared<DocIdOnly>();
+ } else if (name.size() == 10 && name == DocumentOnly::NAME) {
+ return std::make_shared<DocumentOnly>();
} else {
throw vespalib::IllegalArgumentException(
"The only special names (enclosed in '[]') allowed are "
- "id, all, none, not '" + name + "'.");
+ "id, all, none, docid, document; but not '" + name + "'.");
}
}
@@ -109,6 +111,8 @@ FieldSetRepo::serialize(const FieldSet& fieldSet)
return NoFields::NAME;
case FieldSet::Type::DOCID:
return DocIdOnly::NAME;
+ case FieldSet::Type::DOCUMENT_ONLY:
+ return DocumentOnly::NAME;
default:
return "";
}
diff --git a/document/src/vespa/document/fieldset/fieldsets.cpp b/document/src/vespa/document/fieldset/fieldsets.cpp
index 403e220466c..74dac80879a 100644
--- a/document/src/vespa/document/fieldset/fieldsets.cpp
+++ b/document/src/vespa/document/fieldset/fieldsets.cpp
@@ -47,6 +47,7 @@ FieldCollection::contains(const FieldSet& fields) const
case Type::NONE:
case Type::DOCID:
return true;
+ case Type::DOCUMENT_ONLY:
case Type::ALL:
return false;
}
@@ -60,6 +61,12 @@ FieldSet::copyFields(Document& dest, const Document& src, const FieldSet& fields
if (fields.getType() == Type::ALL) {
dest.getFields() = src.getFields();
return;
+ } else if (fields.getType() == Type::DOCUMENT_ONLY) {
+ const auto * actual = src.getType().getFieldSet(DocumentOnly::NAME);
+ if (actual != nullptr) {
+ copyFields(dest, src, actual->asCollection());
+ }
+ return;
}
for (Document::const_iterator it(src.begin()), e(src.end());
it != e; ++it)
@@ -90,6 +97,15 @@ FieldSet::stripFields(Document& doc, const FieldSet& fieldsToKeep)
{
doc.clear();
return;
+ } else if (fieldsToKeep.getType() == Type::DOCUMENT_ONLY) {
+ const auto * actual = doc.getType().getFieldSet(DocumentOnly::NAME);
+ if (actual != nullptr) {
+ return stripFields(doc, actual->asCollection());
+ } else {
+ // XXX - should not happen
+ doc.clear();
+ return;
+ }
}
std::vector<const Field*> fieldsToRemove;
for (Document::const_iterator it(doc.begin()), e(doc.end());
diff --git a/document/src/vespa/document/fieldset/fieldsets.h b/document/src/vespa/document/fieldset/fieldsets.h
index 59cda189018..c92453cc67e 100644
--- a/document/src/vespa/document/fieldset/fieldsets.h
+++ b/document/src/vespa/document/fieldset/fieldsets.h
@@ -33,6 +33,18 @@ public:
Type getType() const override { return Type::DOCID; }
};
+class DocumentOnly final : public FieldSet
+{
+public:
+ static constexpr const char * NAME = "[document]";
+ bool contains(const FieldSet& fields) const override {
+ return fields.getType() == Type::DOCUMENT_ONLY
+ || fields.getType() == Type::DOCID
+ || fields.getType() == Type::NONE;
+ }
+ Type getType() const override { return Type::DOCUMENT_ONLY; }
+};
+
class FieldCollection : public FieldSet
{
public:
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentretriever.cpp b/searchcore/src/vespa/searchcore/proton/server/documentretriever.cpp
index 6285f4ce70f..d3778b4d745 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentretriever.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/documentretriever.cpp
@@ -127,6 +127,7 @@ DocumentRetriever::needFetchFromDocStore(const FieldSet & fieldSet) const {
case FieldSet::Type::NONE:
case FieldSet::Type::DOCID:
return false;
+ case FieldSet::Type::DOCUMENT_ONLY:
case FieldSet::Type::ALL:
return ! _areAllFieldsAttributes;
case FieldSet::Type::FIELD: {
@@ -257,6 +258,14 @@ DocumentRetriever::getPartialDocument(search::DocumentIdT lid, const document::D
populate(lid, *doc, set.getFields());
break;
}
+ case FieldSet::Type::DOCUMENT_ONLY: {
+ const auto * actual = getDocumentType().getFieldSet(document::DocumentOnly::NAME);
+ if (actual != nullptr) {
+ const auto &set = actual->asCollection();
+ populate(lid, *doc, set.getFields());
+ }
+ break;
+ }
case FieldSet::Type::NONE:
case FieldSet::Type::DOCID:
break;