简体   繁体   中英

find whether individual array element exists in the mongodb document's array

Is there a way to find whether the individual element exists in the mongodb document's array.

For Example: If I have a document

{
    "_id": "A",
    "userId": "B",
    "selectedUsers": ["C", "D"]
}

and I have another array as ["E", "C"].
I want to write a query which gives the result as [false, true] when userId and the above array is supplied to it because "E" is not in the selectedUsers array and "C" is in the selectedUsers array.

I Know I can just first find the document with the given userId and then use Array.find() on it for individual element. But I want to know if there's a way to do this in mongodb query.

Also, I am using nodeJS and mongoose.

Just to be clear I need to get the same functionality as the below js code using mongodb query.

// req is the http request
// Selected is the mongoose Model for above document
// usersToCheck = ["E", "C"] (this is the second array)
const result = Selected.findOne({ userId: req.userId});
const { selectedUsers } = result;
const response = usersToCheck.map(uid => {
    if(selectedUsers.some(id => id === uid)){
        return true;
    }
    return false;
})

// response = [false, true]

Now the above code have a complexity of O(n^2) assuming the size of usersToCheck and selectedUsers is n.

I want to some how get the same response as above using mongodb query. So, that I can index the collection based on the selectedUsers array and improve the time required to get the response.

Or, any other way to improve the above code is appreciated.

Thanks in advance for your help.

Try this one:

const result = Selected.aggregate([
  {
    $match: {
      userId: req.userId
    }
  },
  {
    $project: {
      _id: 0,
      result: {
        $map: {
          input: ["E", "C"],
          in: {
            $in: [
              "$$this",
              "$selectedUsers"
            ]
          }
        }
      }
    }
  }
]).exec();
const response = result[0].result;

MongoPlayground

你可以只使用$in

db.collection.find({selectedUsers: {$in: ["E", "C"]}})

how about something like this?

var input = ['E', 'C'];

db.collection.aggregate(
    [
        {
            $match: {
                _id: 'A'
            }
        },
        {
            $unwind: '$selectedUsers'
        },
        {
            $set: {
                has: { $in: ['$selectedUsers', input] }
            }
        },
        {
            $group: {
                _id: null,
                result: { $push: '$has' }
            }
        },
        {
            $project: {
                _id: 0
            }
        }
    ])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM