MongoDB query to update fields with same name - mongodb

I'm using mongodb version v3.4.2
I have a collection with one document.
The document has a complex(not standard) structure that I don't know.
The structure of the document is something like this
{
"time": 9281
"object_1": [
{ "time": 8372 },
{ "time": 3234 }
],
"object_2": {
"time": 2928
}
}
I need to change the values of all fields with name "time".
Can I do this with a single/multiple mongo query?
I tried with :
db.collection.update({}, {$set: {time: 999}})
db.collection.updateMany({}, {$set: {time: 999}})
but only top level occurrencies are updated with the new value.
After the document has been updated with the query, this should be the result:
{
"time":999
"object_1":[{"time":999},{"time":999}]
"object_2":{"time":999}
}

Related

Can't remove object in array using Mongoose

This has been extensively covered here, but none of the solutions seems to be working for me. I'm attempting to remove an object from an array using that object's id. Currently, my Schema is:
const scheduleSchema = new Schema({
//unrelated
_id: ObjectId
shifts: [
{
_id: Types.ObjectId,
name: String,
shift_start: Date,
shift_end: Date,
},
],
});
I've tried almost every variation of something like this:
.findOneAndUpdate(
{ _id: req.params.id },
{
$pull: {
shifts: { _id: new Types.ObjectId(req.params.id) },
},
}
);
Database:
Database Format
Within these variations, the usual response I've gotten has been either an empty array or null.
I was able slightly find a way around this and accomplish the deletion by utilizing the main _id of the Schema (instead of the nested one:
.findOneAndUpdate(
{ _id: <main _id> },
{ $pull: { shifts: { _id: new Types.ObjectId(<nested _id>) } } },
{ new: true }
);
But I was hoping to figure out a way to do this by just using the nested _id. Any suggestions?
The problem you are having currently is you are using the same _id.
Using mongo, update method allows three objects: query, update and options.
query object is the object into collection which will be updated.
update is the action to do into the object (add, change value...).
options different options to add.
Then, assuming you have this collection:
[
{
"_id": 1,
"shifts": [
{
"_id": 2
},
{
"_id": 3
}
]
}
]
If you try to look for a document which _id is 2, obviously response will be empty (example).
Then, if none document has been found, none document will be updated.
What happens if we look for a document using shifts._id:2?
This tells mongo "search a document where shifts field has an object with _id equals to 2". This query works ok (example) but be careful, this returns the WHOLE document, not only the array which match the _id.
This not return:
[
{
"_id": 1,
"shifts": [
{
"_id": 2
}
]
}
]
Using this query mongo returns the ENTIRE document where exists a field called shifts that contains an object with an _id with value 2. This also include the whole array.
So, with tat, you know why find object works. Now adding this to an update query you can create the query:
This one to remove all shifts._id which are equal to 2.
db.collection.update({
"shifts._id": 2
},
{
$pull: {
shifts: {
_id: 2
}
}
})
Example
Or this one to remove shifts._id if parent _id is equal to 1
db.collection.update({
"_id": 1
},
{
$pull: {
shifts: {
_id: 2
}
}
})
Example

How to update/insert into a mongodb collection with the result of aggregate query on the another collection

I have a below aggregate query and I wanted to insert/update this result into another collection.
db.coll1.aggregate([
{
$group:
{
_id: "$collId",
name: {$first:"$name"} ,
type: {$first:"$Type"} ,
startDate: {$first:"$startDate"} ,
endDate: {$first:"$endDate"}
}
}
])
I have another collection coll2, which has fields in the above query and some additional fields too.
I may already have the document created in Coll2 matching the _id:collId in the above query. If this Id matches, I want to update the document with the field values of the result and keep the values of other fields in the document.
If the Id does not exists, it should just create a new document in Coll2.
Is there a way to do it in the MongoDB query. I want to implement this in my Spring application.
We can use $merge to do that. It's supported from Mongo v4.2
db.collection.aggregate([
{
$group:{
"_id":"$collId",
"name": {
$first:"$name"
},
"type":{
$first:"$Type"
},
"startDate":{
$first:"$startDate"
},
"endDate":{
$first:"$endDate"
}
}
},
{
$merge:{
"into":"collection2",
"on":"_id",
"whenMatched":"replace",
"whenNotMatched":"insert"
}
}
])

How to show specific column in mongo db collection

I tried to show particular columns in mongodb colletion.but its not working.how to show particular columnns.
user_collection
[{
"user_name":"hari",
"user_password":"123456"
}]
find_query
db.use_collection.find({},{projection:{user_name:1}})
I got output
[{
"user_name":"hari",
"user_password":"123456"
}]
Excepted output
[{
"user_name":"hari",
}]
Try:
db.use_collection.find({}, {user_name:1, _id: 0 })
In that way you get the field user_name and exclude the _id.
Extra info:
project fields and project fields excluding the id
With aggregate:
db.use_collection.aggregate( [ { $project : { _id: 0, user_name : 1 } } ] )
You can try this
Mongo query:
db.users.aggregate([
{
"$project":
{
"_id": 0,
"first_name": 1,
}
}
])
Or in ruby (Mongoid)
User.collection.aggregate(
[
"$project":
{
"_id": 0,
"first_name": 1,
}
]
)
If you try to inspect the record, you can convert it into an array first (e.g. User.collection.aggregate(...).to_a)
You can use the official mongodb reference when writing in Mongoid, usually you just need to use double quote on the property name on the left hand side, to make it work on Mongoid.
Try:
db.use_collection.find({}, {user_password:0, _id: 0 ,user_name:1 })

Append fields from a document to other document having matching field MongoDB

I am trying to write MongoDB query to accomplish something which is explained below. I don't know whether it is possible in mongoDB or not. I know how to insert a field in single document or multiple document but my problem is little advance to that.
I have a collection (say for "procs") having 5000 documents like:
{
"sid": 1
"procs": [
{
"post_time": 0,
"p_start": 1487303363.8170002,
"pid": 1
}
]
}
Here is the another document-2 from different collection(say for "acqs"):
{
"sn": 10302301,
"date": "2017-12-11",
"sid": 1
"acqs": [{
"aqid": 2,
"aq_end": 1487305607.342
}
]
}
This collection also contains around 5000 documents.
Now i want to insert "sn" and "date" fields from document 2 to document 1 corresponding to same "sid" field values.
so i want output something like this:
{
"sn": 10302301,
"date": "2017-12-11",
"sid": 1
"procs": [{
"post_time": 0,
"p_start": 1487303363.8170002,
"pid": 1
}
]
}
In mongoDb , you can use $lookup
db.procs.aggregrate([
{
$lookup:
{
from: "acqs",
localField: "sid",
foreignField: "sid",
as: "procs_docs"
}
}
])
Result Will be like :
{
"sn": 10302301, "date": "2017-12-11", "sid": 1 ,
"acqs": [{ "aqid": 2, "aq_end": 1487305607.342 } ]
"procs_doc": ["sid": 1,procs:{ "post_time": 0, "p_start": 1487303363.8170002, "pid": 1 } ] }
If you are using mongoose then you can use populate method of mongoose ,which lets you reference documents in other collections.

How to insert multiple documents from a collection as an array field in another document - MongoDB

I'm trying to insert all the documents in the collection "documents" to a new document as an array. the new document suppose to look like that:
{
id=1,
arr=[all the documents from the collection]
}
it tried:
db.results.insert({"id":2,"arr":[]});
db.documents.find().forEach(function(doc){
db.results.update(
{ "id": 2 },
{ $push: { "arr": doc } })
})
it doesn't work.
thank you
I figured it out:
I needed to add flags:
db.results.update({"id": 2}, {$push: {"arr": doc }}, true, false)