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> }
Related
Use case
Adding a field to a specific object in an array of objects using updateOne during a bulkUpdateOps
Blockers
I have been unable to find a way to identify and update a specific object in the subdocument array of a specific record.
I only have access to this DB through MongoDB Compass, and I plan to use the provided mongosh tool.
Data example
Our purchaseorders model looks like this:
{
_id: uuid,
...rest,
documents:[
{
_id:uuid,
forignKey2:string (optional),
keyIWantToAdd:string (optional),
...rest
}
]
}
So if I have
{
_id:*1,
documents:[
{
_id:*2,
forignKey2:'no-test',
...rest
},
{
_id:*3,
forignKey2:'test',
...rest
},
]
}
I want to add a key and value like this (really I'm willing to do anything to set these values, this is just the closest I have been able to get):
var bulkUpdateOps = db.purchaseorders.initializeOrderedBulkOp();
bulkUpdateOps.find('*1').updateOne({
$set:{
documents.[index of document object with forignKey2:'test' or _id:*3 whichever is easier].keyIWantToAdd:'valueIWantToAdd'
}
})
bulkUpdateOps.execute();
Any help or suggestions would be greatly appreciated.
#rickhg12hs posted exactly what I was looking for. For anyone else using mongodb.com/docs/manual/reference/method/Bulk.find.arrayFilters the bulk find is being ran on an array of objects like this: { grades:[ { grade: 85, mean: number } ] }
I have a collection containing posts which are documents containing a timestamp and other data, we could call it global post object.
Whenever an user posts something, a document with the same id as the post id is added to the user's private post collection (under users/userUuid/posts/postId), let's call it private post object.
Each private post object contains a reference to the global post object (stored as a reference object in the document).
This is the structure:
posts: [
"post1" : {
timestamp: 12000000000
data: "abc"
}
"post2" = {
timestamp: 12000000000
data: "abc"
}
]
users: [
"user1" : {
posts: [
"post1": {
ref: reference to post1
}
]
}
]
I have a screen in which I'm querying all the objects under the user's private post collection. Is it possible to sort those based on the timestamp value of the document they reference?
Is it possible to sort those based on the timestamp value of the document they reference?
It seems you are trying to join the two data from two collection in Cloud/Firebase Firestore which is faster if there's a join queries but Firestore has no join queries. There are still ways but they do it differently, most cases they perform multiple read operations, store in array variable and sort it or using collection group query. It still depend on your codes and how you will handle the data, there are some questions that already explain it in multiple questions in Stack Overflow(ex. 1, 2).
I would suggest that it will be easier if you change your Firestore data structure. For example, add field(ex. author) that has a value of userid(ex. users1) to the posts collection so every post has an owner. Use where clause for author field and orderBy clause for timestamp field to sort it desc or asc:
structure:
posts: [
"post1" : {
timestamp: 12000000000
data: "abc"
author: "user1"
}
"post2" = {
timestamp: 12000000000
data: "abc"
author: "user1"
}
]
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
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(?)
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) );