Find document that has string in array - mongodb

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(?)

Related

Filter mongodb data via API requests

I am trying to figure out how to filter data in mongodb Atlas via API requests.
My json structure:
{
_id: ObjectId,
level: number,
names: Array
}
I learned how to filter by _id. I pass the id via url, and fetch data with filter parameter using $oid in the body.
But the question is: how to filter data by level and get the list of data assign to certain level? I don't know what to use instead of $oid 🤷🏻‍♂️ If I just change the id/_id to level I don't receive anything.
const {
query: { id },
method,
} = req
....
const readData = await fetch(`${baseUrl}/find`, {
...fetchOptions,
body: JSON.stringify({
...fetchBody,
filter: { _id: { $oid: id } },
}),
})
The difference here has to do with data types. Your current query, which works when filtering on _id is:
{ _id: { $oid: id } }
The $oid component of this query is related to the fact that you are using the (default) ObjectId type for that field. $oid itself is the extended JSON representation of that data type. Other languages and interfaces have different ways of representing or constructing ObjectIds.
You have a different data type for your level field - a number. So attempting to do a similar query on that field such as:
{ level: { $oid: <value>} }
Will either result in the query failing (if the ObjectId is unable to be created from <value> due to its specific structure) or in no documents being returned (since no documents have ObjectIds for this field).
Removing the wrapping $oid should solve the problem:
{ level: <value> }

Querying mongodb for a nested object

I have Book objects in my mongoDb that look like this (very simplified):
{
"_id": ObjectId("620e341dbf575892d9396dc2"),
"title": "my title",
"author": {
"_id": ObjectId("620e341dbf575892d9396dd4"),
"surname": "My surname"
}
}
I'm trying to query and get all books by an author, and so far I've tried:
const booksByAuthor = await Book.find({ author: { _id: "620e341dbf575892d9396dd4" } });
and
const booksByAuthor = await Book.find({ 'author._id': "620e341dbf575892d9396dd4" } );
But in no case I'm getting the existing books from the given author, and I'm only getting empty arrays.
What am I doing wrong?
The problem for 1st query:
When you want to query in a nested field you have to use dot notation as you do in the second query.
The problem to not use dot notation is mongo match the entire object (even the fields order) so is not a good way... you can check simple examples like:
This one: The object is found because the object is exactly the same.
Another this one where the object has the same fields and values from two objects in the collection but... querying using an object the order matters, so only returns one.
The problem for 2nd query:
I think the problem here is you are matching string vs ObjectId. The syntaxis is correct (dot notation) but when mondo match the values one of them is string and another is ObjectId.
So you can try this query:
const booksByAuthor = await Book.find({ 'author._id': mongoose.Types.ObjectId("620e341dbf575892d9396dd4") } );
Check this example with your query, matching string and ObjectId none result is returned, but parsing string to ObjectId... magic appears

Mongodb: Query and array with an array

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

Mongoose findOneAndUpdate an array within an array within a document

I'm trying to update an array that sits inside another array in a document. The schema is like this:
const projectSchema = new mongoose.Schema({
stakeholders: [{
stakeholderTitle: {
type: String,
},
...
subgroup: [{
subgroupTitle: {
type: String
},
subgroupPercent: {
type: Number,
}
}]
}],
and I'm trying to update the 'subgroup' array. I have got the query to work on its parent (the stakeholder array) with the positional $ operator, using the answer to this question I asked previously. So my query looks like this.....
await db.findOneAndUpdate({ find by the id }, { "stakeholders.$.stakeholderTitle": req.body.stakeholderTitle, ... "stakeholders.$.subgroup": req.body.subgroup })
However, this query doesn't work for the 'stakeholders subgroup' array, and makes it null. Looking through the mongo docs for the positional operator it states that 'The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value', which I guess might be my problem.
So how can I do this with a findOneAndUpdate query?
From what I see is you have to specify the object you want to update inside the subgroup array. Try this - (i.e I'm updating the subgroupTitle of the subgroup array);
await db.findOneAndUpdate(
{
_id: userId,
"stakeholders.stakeholderTitle": req.body.stakeholderTitle,
"stakeholders.stakeholderTitle.subgroup.subgroupTitle": req.body.subgroupTitle
},
{$set: {
"stakeholders.stakeholderTitle.subgroup.$.subgroupPercent": somePercentValue,
}
},
);
Also note, it's only the array that you find that you can update. It might not be exactly what you want, but its a step closer

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) );