How can I insert value in array inside object field in mongodb? - mongodb

How can I insert an value in "total" array where pid = "123"
{
"_id" : ObjectId("625bc1983016ed5208bbdf90"),
"NAME" : "XYZ",
"data" : [
{
"pid" : "123",
"total" : [ ]
},
{
"pid" : "456",
"total" : [ ]
}
]
}

The right way is:
db.collection.update({
data: {
$elemMatch: {
pid: "123"
}
}
},
{
$set: {
"data.$.buyers": "some name"
}
})
$elemMatch allows you to match more than one component within the same array element and then you can use $set to update the specific element.
You can run it here to check the same query https://mongoplayground.net/p/lveZw-8wkZ0
You can also have a look at documentation of $elemMatch in this link.
Let me know if you face any issue.

Related

Update inner array in multiple array document

I am trying this question... I don't want use the "_id" : "12", field..
{
"_id" : ObjectId("62622dd73905f04f59db2971"),
"array1" : [
{
"_id" : "12",
"array2" : [
{
"_id" : "123",
"answeredBy" : []
},
{
"_id" : "124",
"answeredBy" : []
}
]
}
]
}
I am trying to update using the following query
db.getCollection('nestedArray').updateMany(
{'array1.array2._id':'123'},
{$push:{'array1.array2.$[inner].answeredBy':'success'}},
{arrayFilters:[{'inner._id':'123'}]}
)
But I am getting the following error:
"errmsg" : "The path 'array1.array2' must exist in the document in
order to apply array updates.",
I just trying to understand what is wrong with the code....
add $[] between array1 and array2
Update Nested Arrays in Conjunction with $[]
db.collection.update({
"array1.array2._id": "123"
},
{
$push: {
"array1.$[].array2.$[inner].answeredBy": "success"
}
},
{
arrayFilters: [
{
"inner._id": "123"
}
]
})
mongoplayground

Search array for dates within a range

I am new to MongoDB, keep that in mind as I ask my questions please. I have the following collection named 'documents' where I have an array named attributes which contains key:value pairs of different types.
{
"_id" : ObjectId("5d376c67f6c305c7571f7dd7"),
"name" : "testContract.pdf",
"fileType" : "pdf",
"attributes" : [
{
"abc" : 1
},
{
"def" : ISODate("2012-12-01T08:00:00Z")
},
{
"ghi" : "test"
}
]
}
{
"_id" : ObjectId("5d376ca4f6c305c7571f7dd8"),
"name" : "1099.pdf",
"fileType" : "pdf",
"attributes" : [
{
"def" : ISODate("2012-06-03T07:00:00Z")
},
{
"ghi" : "taxes"
}
]
}
What I would like to do is return one or more documents from this collection that fit within a date range. For example I can return all documents that have a fileType of 'pdf' with the following query -->
db.documents.find({"fileType":"pdf"});
But what I am trying to figure out is can I search an array containing different data types like dates in a range successfully while also being able to search for strings. I can also search the attributes array with the following -->
db.documents.find({"attributes":{"ghi":"test"}});
Here is an example of what I am trying to get but it is not working...
db.documents.find({'attributes':$match:{[{'def':{$gte:new Date('2011-11-30')}}]}});
Is something like this what you are looking for?
Based on the following documents:
{
"_id" : ObjectId("5d38aad64850fbd5d13f14bd"),
"name" : "testxx.pdf",
"attributes" : [
{
"abc" : 1
},
{
"def" : ISODate("2012-12-01T08:00:00Z")
},
{
"ghi" : "test"
}
]
}
{
"_id" : ObjectId("5d38b0eae4adbe945b6cbb89"),
"name" : "testyy.pdf",
"attributes" : [
{
"abc" : 2
},
{
"def" : ISODate("2013-12-01T08:00:00Z")
},
{
"ghi" : "test1"
}
]
}
{
"_id" : ObjectId("5d38b12f21e647b8d384d841"),
"name" : "testzz.pdf",
"attributes" : [
{
"abc" : 3
},
{
"def" : ISODate("2012-05-01T08:00:00Z")
},
{
"ghi" : "test"
}
]
}
Query def > 2010/11/30 - returns all 3 docs above
db.chkdates.find({'attributes.def':{$gte:new Date(2010,11,30)}}).pretty()
Adding another key/value pair and range looks like:
db.chkdates.find({'attributes.def':{$gte:new Date(2011,12,12),
$lte:new Date(2012,10,12)},
'attributes.ghi':'test'}).pretty()
Returns only 1 document:
{
"_id" : ObjectId("5d38b12f21e647b8d384d841"),
"name" : "testzz.pdf",
"attributes" : [
{
"abc" : 3
},
{
"def" : ISODate("2012-05-01T08:00:00Z")
},
{
"ghi" : "test"
}
]
}
You can use the $gte and $lte for querying within a date range. It would look something like this:
{'def': { $gte: qryDateFrom, $lte: qryDateTo }}
Depending on if you're using aggregate pipleline or a regular mongoose query, you'd just apply this accordingly.
For instance, using $match in an aggregate with a string match included, it would look like this:
$match: {
$and: [
{'id': { $ne: req.user._id }},
{'def': { $gte: qryDateFrom, $lte: qryDateTo }}
]
}

$pull operator in MongoDB

{
"_id" : ObjectId("5badfada90fd543fd8aa7f96"),
"__v" : 0,
"deleted" : false,
"groups" : [
{
"group" : "grp",
"_id" : ObjectId("5bae09a601123357e58b66a2"),
"activities" : [
ObjectId("5bae09a601123357e58b66a3"),
ObjectId("5bae10de01123357e58b66a6")
]
},
{
"group" : "123",
"_id" : ObjectId("5bae0f1001123357e58b66a4"),
"activities" : [
ObjectId("5bae0f1001123357e58b66a5")
]
}
],
"nextActivityId" : 22,
"name" : "test",
"year" : "1",
"status" : "2",
"vision" : ObjectId("5bab2f4872acf42a81c124d0")
}
The Above Schema is a "Plan" Schema
I have to write a query for removing an Activity inside "activities" array. What will be the optimum solution for this? And how will I use $pull to achieve this
This was my solution, but it will delete the complete groups array
Plan.update({ _id: PLAN ID }, { $pull: { groups: { activities: ACTIVITY ID } } })
PLAN ID BEING: "_id" : ObjectId("5badfada90fd543fd8aa7f96"),
ACTIVITY ID FOR EXAMPLE BEING: ObjectId("5bae09a601123357e58b66a3")
Thank you!
You need to use the positional $ update operator.
db.Plan.update(
{ "_id" : PLAN ID },
{ "$pull": { "groups.$.activities": ACTIVITY ID } }
)
You can try this,
db.Plan.update({ _id: ObjectId("5badfada90fd543fd8aa7f96"),"groups.activities":{$in:[ ObjectId("5bae09a601123357e58b66a3") ]}},
{ $pull: { "groups.$.activities": ObjectId("5bae09a601123357e58b66a3") } });
The positional operator did not find the match needed from the query warning when use $ only update object.

Update a object field in an array

In mondodb I want to update a field of an object within an array. The example database looks like this:
{
"_id" : ObjectId("5ad237559d30d918c89c7f46"),
"myArray" : [
{
"name" : "a",
"name2" : "a",
"value" : 900000 //<--- instead of this...
},
{
"name" : "b",
"name2" : "b",
"value" : 0
}
]
},
{
"_id" : ObjectId("5ad238049d30d918c89c7f47"),
"myArray" : [
{
"name" : "b",
"name2" : "b",
"value" : 0
},
{
"name" : "c",
"name2" : "a",
"value" : 0 //... I want to update this
}
]
}
I want to update the last value field by querying name:c AND name2:a. I tried it with the following instruction, but it sets the value of the first object (name:a name2:a). Does the problem lie near the $ char?
db.test.updateOne({$and:[{"myArray.name" : "c"}, {"myArray.name2" : "a"}]},
{$set:{"myArray.$.value" : 900000}})
You need to do an $elemMatch to match the specific item in the array and then you can use the positional operator:
db.test.updateOne(
{ "myArray": { $elemMatch: { "name": "c", "name2"; "a" } } },
{ $set: { "myArray.$.value": 900000 } }
);
You can use arrayFilters.
db.test.updateOne({}, {$set:{"myArray.$[element].value" : 900000}} {
multi: true,
arrayFilters: [ {$and:[{"element.name" : "c"}, {"element.name2" : "a"}]} ]
},
)
Sorry, I have no mongodb right there to test it, the query will probably need to be tuned a little

Matched elements from mongodb records

Suppose I have following documents in my collection
{
"_id":ObjectId("562e7c594c12942f08fe4192"),
"tags" : [
{
"tagName" : "fun",
"created" : ISODate("2016-01-22T06:13:56.510Z")
},
{
"tagName" : "cool",
"created" : ISODate("2016-01-22T06:13:56.509Z")
},
{
"tagName" : "good",
"created" : ISODate("2016-01-22T06:13:56.509Z")
}
]
},
{
"_id":ObjectId("562e7c594c12942f08fe4193"),
"tags" : [
{
"tagName" : "super",
"created" : ISODate("2016-01-22T06:13:56.509Z")
},
{
"tagName" : "fun",
"created" : ISODate("2016-01-22T06:13:56.509Z")
}
]
}
I want to search relative tags and want to display tag array only.
How can I query to get the list of tag names?
To only query a specific field in MongoDB you can use the find method with the projection parameter:
https://docs.mongodb.org/manual/reference/method/db.collection.find/
db.test.find({}, {"tags.tagName":1,"_id":0}).pretty()
{
"tags" : [
{
"tagName" : "fun"
},
{
"tagName" : "cool"
},
{
"tagName" : "good"
}
]
}
The first parameter is blank {} because you don't have any query and the second parameter is your projection. With an embedded document you have to use the dot notation "tags.tagName". The "_id":0 to not display the _id field.