I am working with 1.000 documets in a collection in MongoDb. Each document can be made of many topics, and a topic can be made of many keywords.
The mongo structure for each document is the following:
_id:ObjectId(6d5fc0922982bb550e08502d),
id_doc:"1234-678-436-42"
topic:Array
keywords:Array
The key topic is an array of objects o this type
type:"topic"
label:"work"
While, the keywords key is an array of objects, very similar to "topic":
type:"keyword"
value:"programmer"
label:"work"
Label represents in both cases the topic of the doc!
What I want is to list all the documents (id_doc) where a topic appears in the "topic" array, but never in the "keyword" array.
CodePudding user response:
One option is using $filter
:
- count the number of items in
topic
which theirlabel
is not present in as avalue
of an item onkeywords
. Save this count ascondMatch
$match
only document withcondMatch
greater than 0
db.collection.aggregate([
{$set: {condMatch: {
$size: {
$filter: {
input: "$topic",
cond: {$not: {$in: ["$$this.label", "$keywords.value"]}}
}
}
}
}
},
{$match: {condMatch: {$gt: 0}}},
{$unset: "condMatch"}
])
See how it works on the playground example
CodePudding user response:
Query
- takes the intersection of
topic.label
withkeywords.label
- if empty then no common members, so document passes the filter
*not sure if you want this, if not if you can give 1-2 documents in json text, and the expected output
aggregate(
[{"$match":
{"$expr":
{"$eq":
[{"$setIntersection": ["$topic.label", "$keywords.label"]}, []]}}}])