Home > Software design >  Mongo aggregator query: get list of documents depending on condition
Mongo aggregator query: get list of documents depending on condition

Time:07-19

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:

  1. count the number of items in topic which their label is not present in as a value of an item on keywords. Save this count as condMatch
  2. $match only document with condMatch 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 with keywords.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

Playmongo

aggregate(
[{"$match": 
   {"$expr": 
     {"$eq": 
       [{"$setIntersection": ["$topic.label", "$keywords.label"]}, []]}}}])
  • Related