Mongodb: Query and array with an array - mongodb

I'm kind of stuck how to query an array with an array, in mongodb.
In the below example, "tag" is a string - and "newTotalTags" is an array of tags.
let allShares = await ShareModel.find({tag: { $in: newTotalTags}}).lean()
I need to change this logic from tag (single string) to tags (array).
So I have an array (newTotalTags) and I need to query a schema property which is also an array.
Any tips?

you can try $all instead of $in,
let allShares = await ShareModel.find({ tag: { $all: newTotalTags } }).lean()
Playground

Related

Mongoose find query - specific items or empty array

I'm trying to build a filter where it should be possible to query all items selected in an array, but also to show documents where the property has not been set.
returning all specific from an array works fine with below
searchCriteria.filter1 = {
$in: array.category,
};
searchCriteria.filter2 = {
$in: array.carbrand,
};
//Then the data if fetched
const fetchedData = await Activity.find(searchCriteria)
.sort({ date: -1 })
.limit(limit)
.skip(startIndex)
.exec();
However, sometimes users have not added a category, and it's just a empty array. My goal is to get all of these empty arrays as well as the specific arrays.
so something like:
searchCriteria.filter2 = {
$in: array.carbrand OR is []
};
Any suggestions?
One way you could approach this is indeed to use the $or operator. But since $in is logically an OR for a single value, you should be able to just append [] to the list being used for comparison by the $in operator.
The approach is demonstrated in this playground example.
I believe you could adjust the code in a manner similar to this:
searchCriteria.filter2 = {
$in: [...array.carbrand, []]
};

MongoDB : Match with element in an array

I am working on a collection called Publications. Each publication has an array of objectives which are ids. I have also a custom array of objectives hand written. Now, I want to select all the publications that contains at least one element of the custom objectives array in their objectives. How can I do that ?
I've been trying to make this works with '$setIntersection' then '$count' and verify that the count is greater than 0 but I don't know how to implement this.
Example :
publication_1: {
'_id': ObjectId("sdfsdf46543")
'objectives': [ObjectId("1654351456341"), ObjectId("123456789")]
}
publication_2: {
'_id': ObjectId("sdfs216546543")
'objectives': [ObjectId("1654351456341"), ObjectId("46531132")]
}
custom_array = [ObjectId("123456789"), ObjectId("2416315463")]
The mongo query should return publication_1.
You can do like the following:
db.publications.find({
"objectives": {
"$in": [
ObjectId("123456789"),
ObjectId("2416315463")
]
}
})
Notice: "123456789" is not a valid ObjectId so the query itself may not work. Here is the working example
Mongodb playground link: https://mongoplayground.net/p/MbZK99Pd5YR
objectives is an array of objects, I guess you can just query that field directly:
let custom_array = [ObjectId("123456789"), ObjectId("2416315463")];
// You can search the array with $in property.
let result = await Model.find({ objectives: {$in : custom_array} })

Find document that has string in array

At this moment I have a Mongoose/MongoDB schema which has the following field:
cuisines: [{
type: String
}],
I'm trying to find documents that contain one of the results inside the array.. so the array could look like:
[BBQ, Chicken, Asian]
My query currently returns no result:
caterers = await Caterer.find({ cuisines: { $in: [req.body.cuisine] } })
Is there an alternative to $in that finds all documents in which the string passed in the req.body is present?
The string I'm passing in req.body.cuisine is BBQ, however, unless I specify all results stored in the Array, I get no results(?)

Is There a way to fetch data from mongodb Collection using in Array function. if array id is string

I have Generating the Dynamic Report from mongodb Collections. I fetch Data from one Collection and e.g client and take all client id in Array e.g ["5b7869dff0be71721f53d2e3","5b7869dff0be71721f53d2e4","5b7869dff0be71721f53d2e3"] When i I fetch data from other collection using In Array e.g {"clientId": { $in: inArray } } it give me empty result. because in array work if i put { "clientId": { $in: [ObjectId('5b785f243cc6c746af635dc8')] } } "ObjectId" word before the id. My Question is how i Put this ObjectId work in the array.
you can use map to map the array to an array of ObjectId
inArray = inArray.map( value => ObjectId(value) );

Mongo $in query with case-insensitivity

I'm using Mongoose.js to perform an $in query, like so:
userModel.find({
'twitter_username': {
$in: friends
}
})
friends is just an array of strings. However, I'm having some case issues, and wondering if I can use Mongo's $regex functionality to make this $in query case-insensitive?
From the docs:
To include a regular expression in an $in query expression, you can
only use JavaScript regular expression objects (i.e. /pattern/ ). For
example:
{ name: { $in: [ /^acme/i, /^ack/ ] } }
One way is to create regular Expression for each Match and form the friends array.
var friends = [/^name1$/i,/^name2$/i];
or,
var friends = [/^(name1|name2)$/i]
userModel.find({"twitter_username":{$in:friends }})
Its a little tricky to do something like that
at first you should convert friends to new regex array list with:
var insesitiveFriends = [];
friends.forEach(function(item)
{
var re = new RegExp(item, "i");
insesitiveFriends.push(re);
})
then run the query
db.test.find(
{
'twitter_username':
{
$in: insesitiveFriends
}
})
I have the sample documents in test collection
/* 0 */
{
"_id" : ObjectId("5485e2111bb8a63952bc933d"),
"twitter_username" : "David"
}
/* 1 */
{
"_id" : ObjectId("5485e2111bb8a63952bc933e"),
"twitter_username" : "david"
}
and with var friends = ['DAvid','bob']; I got both documents
Sadly, mongodb tends to be pretty case-sensitive at the core. You have a couple of options:
1) Create a separate field that is a lowercase'd version of the twitter_username, and index that one instead. Your object would have twitter_username and twitter_username_lc. The non-lowerecase one you can use for display etc, but the lowercase one you index and use in your where clause etc.
This is the route I chose to go for my application.
2) Create a really ugly regex from your string of usernames in a loop prior to your find, then pass it in:
db.users.find({handle:{$regex: /^benhowdle89|^will shaver|^superman/i } })
Note that using the 'starts with' ^ carrot performs better if the field is indexed.