8 #include "knowrob/storage/mongo/MongoTaxonomy.h"
9 #include "knowrob/storage/mongo/Pipeline.h"
10 #include "knowrob/semweb/rdfs.h"
17 const std::shared_ptr<mongo::Collection> &tripleCollection,
18 const std::shared_ptr<mongo::Collection> &oneCollection,
20 : tripleCollection_(tripleCollection), oneCollection_(oneCollection), vocabulary_(vocabulary) {
23 template<
typename ResourceType>
24 static void bulkUpdateTaxonomy(
25 std::shared_ptr<mongo::BulkOperation> &bulk,
26 std::shared_ptr<Vocabulary> &vocabulary,
27 std::string_view taxonomyRelation,
28 const std::vector<MongoTaxonomy::StringPair> &assertions) {
29 if (assertions.empty()) {
return; }
31 std::set<MongoTaxonomy::StringPair> invalidAssertions;
32 for (
auto &assertion: assertions) {
35 auto resource = vocabulary->define<ResourceType>(assertion.first);
36 resource->forallChildren([&invalidAssertions](
const ResourceType &child,
const ResourceType &directParent) {
37 invalidAssertions.insert({child.iri(), directParent.iri()});
41 for (
auto &assertion: invalidAssertions) {
42 auto query = bson_new();
43 BSON_APPEND_UTF8(query,
"s", assertion.first.data());
44 BSON_APPEND_UTF8(query,
"p", taxonomyRelation.data());
45 BSON_APPEND_UTF8(query,
"o", assertion.second.data());
47 auto update = bson_new();
48 bson_t setDoc, setArray;
49 BSON_APPEND_DOCUMENT_BEGIN(update,
"$set", &setDoc);
50 BSON_APPEND_ARRAY_BEGIN(&setDoc,
"o*", &setArray);
52 auto cls = vocabulary->define<ResourceType>(assertion.second);
53 uint32_t numParents = 0;
54 cls->forallParents([&setArray, &numParents](
const ResourceType &parent) {
55 auto arrayKey = std::to_string(numParents++);
56 BSON_APPEND_UTF8(&setArray, arrayKey.c_str(), parent.iri().data());
59 bson_append_array_end(&setDoc, &setArray);
60 bson_append_document_end(update, &setDoc);
62 bulk->pushUpdate(query, update);
69 static void bulkUpdateTriples_insert(
70 std::shared_ptr<mongo::BulkOperation> &bulk,
71 std::shared_ptr<Vocabulary> &vocabulary,
72 const std::set<std::string_view> &invalidPropertyAssertions) {
73 for (
auto &invalidProperty: invalidPropertyAssertions) {
75 auto query = bson_new();
76 BSON_APPEND_UTF8(query,
"p*", invalidProperty.data());
80 auto update = bson_new();
81 bson_t addToSetDoc, addToSetEach, addToSetArray;
82 BSON_APPEND_DOCUMENT_BEGIN(update,
"$addToSet", &addToSetDoc);
83 BSON_APPEND_DOCUMENT_BEGIN(&addToSetDoc,
"p*", &addToSetEach);
84 BSON_APPEND_ARRAY_BEGIN(&addToSetEach,
"$each", &addToSetArray);
86 auto resource = vocabulary->define<
Property>(invalidProperty);
87 uint32_t numParents = 0;
89 auto arrayKey = std::to_string(numParents++);
90 BSON_APPEND_UTF8(&addToSetArray, arrayKey.c_str(), parent.
iri().data());
93 bson_append_array_end(&addToSetEach, &addToSetArray);
94 bson_append_document_end(&addToSetDoc, &addToSetEach);
95 bson_append_document_end(update, &addToSetDoc);
96 bulk->pushUpdate(query, update);
103 static void lookupParents(
105 const std::string_view &collection,
106 const std::string_view &entity,
107 const std::string_view &relation) {
112 BSON_APPEND_UTF8(lookupStage,
"from", collection.data());
113 BSON_APPEND_UTF8(lookupStage,
"as",
"parents");
114 BSON_APPEND_ARRAY_BEGIN(lookupStage,
"pipeline", &lookupArray);
116 Pipeline lookupPipeline(&lookupArray);
118 auto matchStage = lookupPipeline.appendStageBegin(
"$match");
119 BSON_APPEND_UTF8(matchStage,
"s", entity.data());
120 BSON_APPEND_UTF8(matchStage,
"p", relation.data());
121 lookupPipeline.appendStageEnd(matchStage);
123 lookupPipeline.project(
"o*");
125 lookupPipeline.unwind(
"$o*");
127 bson_append_array_end(lookupStage, &lookupArray);
132 bson_t parentsDoc, mapDoc;
134 BSON_APPEND_DOCUMENT_BEGIN(setStage,
"parents", &parentsDoc);
136 BSON_APPEND_DOCUMENT_BEGIN(&parentsDoc,
"$map", &mapDoc);
138 BSON_APPEND_UTF8(&mapDoc,
"input",
"$parents");
139 BSON_APPEND_UTF8(&mapDoc,
"in",
"$$this.o*");
141 bson_append_document_end(&parentsDoc, &mapDoc);
143 bson_append_document_end(setStage, &parentsDoc);
147 static void bulkUpdateTriples_remove(
148 std::shared_ptr<mongo::BulkOperation> &bulk,
149 std::shared_ptr<Vocabulary>& ,
150 std::string_view tripleCollectionName,
151 const std::set<std::string_view> &invalidPropertyAssertions) {
152 for (
auto &invalidProperty: invalidPropertyAssertions) {
154 auto query = bson_new();
155 BSON_APPEND_UTF8(query,
"p*", invalidProperty.data());
158 auto update = bson_new();
159 bson_t pipelineArray;
160 BSON_APPEND_ARRAY_BEGIN(update,
"pipeline", &pipelineArray);
164 lookupParents(pipeline, tripleCollectionName, invalidProperty,
rdfs::subPropertyOf->stringForm());
167 BSON_APPEND_UTF8(setDoc,
"p*",
"$parents");
172 bson_append_array_end(update, &pipelineArray);
174 bulk->pushUpdate(query, update);
177 bson_destroy(update);
182 const std::vector<StringPair> &subClassAssertions,
183 const std::vector<StringPair> &subPropertyAssertions) {
184 update(subClassAssertions, subPropertyAssertions,
true);
188 const std::vector<StringPair> &subClassAssertions,
189 const std::vector<StringPair> &subPropertyAssertions) {
190 update(subClassAssertions, subPropertyAssertions,
false);
194 const std::vector<StringPair> &subClassAssertions,
195 const std::vector<StringPair> &subPropertyAssertions,
200 if (subClassAssertions.empty() && subPropertyAssertions.empty())
return;
207 if (!subClassAssertions.empty()) {
210 if (!subPropertyAssertions.empty()) {
215 if (!subPropertyAssertions.empty()) {
216 std::set<std::string_view> invalidPropertyAssertions;
217 for (
auto &assertion: subPropertyAssertions) {
218 invalidPropertyAssertions.insert(assertion.first);
221 bulkUpdateTriples_insert(bulk,
vocabulary_, invalidPropertyAssertions);
227 if (!bulk->empty()) {
void update(const std::vector< StringPair > &subClassAssertions, const std::vector< StringPair > &subPropertyAssertions, bool isInsert)
void updateRemove(const std::vector< StringPair > &subClassAssertions, const std::vector< StringPair > &subPropertyAssertions)
std::shared_ptr< mongo::Collection > tripleCollection_
void updateInsert(const std::vector< StringPair > &subClassAssertions, const std::vector< StringPair > &subPropertyAssertions)
MongoTaxonomy(const std::shared_ptr< mongo::Collection > &tripleCollection, const std::shared_ptr< mongo::Collection > &oneCollection, const VocabularyPtr &vocabulary)
VocabularyPtr vocabulary_
void appendStageEnd(bson_t *stage)
bson_t * appendStageBegin()
void project(std::string_view field)
void forallParents(const PropertyVisitor &visitor, bool includeSelf=true, bool skipDuplicates=true)
const IRIAtomPtr subPropertyOf
const IRIAtomPtr subClassOf
std::shared_ptr< Vocabulary > VocabularyPtr