'How to Insert new documents according to a condition that can be appliyed on one of them

I have a collection where I store unique uID for a user and I also have to register them manually. While registration I pass multiple IDs in an array and now I want to query if any of those uIDs provided while registration match existing uID from registered collection, I want to return those document or simply a truth value which will tell that users exist so that I abort registration and assign another id for a user.

const uniqueIDs = [ "123", "156", "148"]

If required I can run map function to get these values as object of arrays such as

[
{
    uID : "123",
},
{
    uID : "156",
},
{
    uID : "148",
},
]

Example from existing collection:

{
    uID : "123",
    country : "abc"
},
{
    uID : "486",
    country : "def"
},
{
    uID : "958",
    country : "jkl"
},

Now my question is can I query my collection from mapped array or array of uiDs so that I find existing documents? If none documents found, can I insert multiple documents from this unique uID from insertMany like function?



Solution 1:[1]

There is a solution for this, although I would say this is more of an hack than a common practice.

You could do something like:

db.collection.aggregate([
  {
    $facet: {
      addition: [
        {$limit: 1},
        {$project: {
            _id: 0,
            data: [
              {
                uID: "333",
                country: "defrr"
              },
              {
                uID: "222",
                country: "jklyy"
              }
            ]
          }
        }
      ],
      found: [
        {$match: {"uID": {$in: ["123", "156", "148"]}}}
      ]
    }
  },
  {
    $project: {
      data: {
        $cond: [{$lt: [{$size: "$found"}, 1]},
          {$arrayElemAt: ["$addition", 0]}, {data:'errorCase'}
        ]
      }
    }
  },
  {$unwind: "$data.data"},
  {$replaceRoot: {newRoot: "$data.data"}
  },
  {
    $merge: {
      into: "collection",
      on: "uID"
    }
  }
])

This is an aggregation pipeline with a $merge step at the end, in order to insert new documents into the collection. The $facet steps builds the documents you want to insert and checks the condition. The $project with the $cond override it with a data that will return an error in case the condition founds existing uID.

There are limitation to this hack. First you need to have at least one document in your collection before running it, since it uses it as a base to create the new documents. Second, in order to use the $merge step you need to create a unique index on the uID.

At the end, if there are no documents with the uID in the list it will insert the new documents. If there are documents with the uID in the list it will return an error.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 nimrod serok