skip to Main Content

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.

2

Answers


  1. 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

    Login or Signup to reply.
  2. 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"]}, []]}}}])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search