add field to document mongodb keeping previous data - mongodb

I'm trying to add a new field to a document
/* 1 */
{
"_id" : ObjectId("5d3b1d8c708bf66fc760afb6"),
"user" : "myuser",
"password" : "$2y$10$Oh.RKbvf4eT5gozLnD7A0uS5C/k6YluYw0k7uShPD2Elu6FKNBQn2"
}
/* 2 */
{
"_id" : ObjectId("5d3c4e70faa55a342c08c40a"),
"user" : "user2",
"pass" : "$2y$10$Oh.RKbvf4eT5gozLnD7A0uS5C/k6YluYw0k7uShPD2Elu6FKNBQn2"
}
with the comand
db.users.update({"user":"user2"},{"widgets":1})
But then the document that matches previous info is lost
/* 2 */
{
"_id" : ObjectId("5d3c4e70faa55a342c08c40a"),
"widgets" : 1.0
}
How can I update keeping the preious data of the document?

You are missing $set here. If you donot provide $set then all the fields will be replaced with the provided one in your case user and pass is replaced with widgets. As mention in docs
db.users.update({"user":"user2"},{$set: {"widgets":1}})

Related

How to copy data from one collection to another existing collection in MongoDB

I have a coll-1 and coll-2 in MongoDB. So, I need to copy data from coll-1 to coll-2 without disturbing collection data(both two collections are in same DB) and I don't want to do mongoexport and mongoimport because of these collection lots of data every time when we need to update little data I should be convenient.
As you're on mongoDB V4.2 and your two collections are in same database and are existing, you need to use $merge :
Try this query :
db.getCollection('coll-1').aggregate( [
{ $merge : { into: { coll: "coll-2" }, on: "_id", whenNotMatched: "insert" } }
])
Documents in col-1 :
/* 1 */
{
"_id" : ObjectId("5e1f7ac3f35652fb779fcf3e"),
"random1" : 1
}
/* 2 */
{
"_id" : ObjectId("5e1f7acff35652fb779fd310"),
"random1" : 2
}
Documents in col-2 :
/* 1 */
{
"_id" : ObjectId("5e1f7adcf35652fb779fdb42"),
"random2" : 1
}
/* 2 */
{
"_id" : ObjectId("5e1f7ae5f35652fb779fde24"),
"random2" : 2
}
Result :
/* 1 */
{
"_id" : ObjectId("5e1f7adcf35652fb779fdb42"),
"random2" : 1
}
/* 2 */
{
"_id" : ObjectId("5e1f7ae5f35652fb779fde24"),
"random2" : 2
}
/* 3 */
{
"_id" : ObjectId("5e1f7ac3f35652fb779fcf3e"),
"random1" : 1
}
/* 4 */
{
"_id" : ObjectId("5e1f7acff35652fb779fd310"),
"random1" : 2
}
As I wanted to write everything in coll-1 to coll-2, I don't have any stages in aggregation prior to $merge, You need to have this $merge as last stage in aggregation pipeline (For testing purpose you can actually remove it & validate the data through couple of dry runs & then execute the actual operation). Also $merge has a lot of options can be passed in few like - What to do if field values of on does match & few other options, So please go through the MongoDB documentation.

MongoDB - update an existing document in a collection

I have a collection called user_roles and it contains a field called rights which is an array of strings.
I want to update a document within user_roles collection that has _id = 5b1509f8b95b4bfe2b638508 by appending a new string element into the rights field.
So basically, after this update collection should hold the additional element "ui.dealers.measures.retrieve" as shown below.
{
"_id" : ObjectId("5b1509f8b95b4bfe2b638508"),
"type" : "coach",
"name" : "Coach",
"flavours" : {
"coach" : NumberInt(1)
},
"rights" : [
"ui.dealers.retrieve",
"ui.dealers.dossier.retrieve",
"ui.dealers.dossier.update",
"ui.dealers.documents.retrieve",
"ui.dealers.documents.create",
"ui.dealers.documents.delete",
"ui.dealers.events.retrieve",
"ui.dealers.events.create",
"ui.dealers.events.update",
"ui.dealers.events.export",
"ui.dealers.events.delete",
"ui.dealers.kpis.retrieve",
"ui.dealers.kpis.update",
"ui.dealers.blueprints.retrieve",
"ui.dealers.blueprints.create",
"ui.dealers.gap.retrieve",
"ui.dealers.gap.update",
"ui.dealers.measures.create",
"ui.dealers.surveys.retrieve",
"ui.dealers.surveys.update",
"ui.dealers.measures.retrieve"
],
"createdAt" : ISODate("2018-06-04T09:44:24.394+0000"),
"updatedAt" : ISODate("2018-06-04T10:01:56.428+0000")
}
Please try this
db.collection.update({_id:ObjectId("5b1509f8b95b4bfe2b638508")},{
$push:{
"rights":"ui.dealers.measures.retrieve"
}
})

mongodb accessing subdocuments

I have a collection (users) which looks very much the same as mentioned below.
db.users.find().pretty();
{
"_id" : ObjectId("5773fc2826e0b6cf532569ca"),
"user" : {
"login" : "tester"
}
}
{
"_id" : ObjectId("5773fd6426e0b6cf532569cb"),
"user" : {
"login" : "tester",
"name" : "anil"
}
}
When I do
> db.users.find({"user":{"login":"tester"}});
I get this as the result
{ "_id" : ObjectId("5773fc2826e0b6cf532569ca"), "user" : { "login" : "tester" } }
However when I do below, I get no records.
db.users.find({"user":{"name":"anil"}});
>
so my question is why does the second query returns no response ?
Also, based on the examples above, I am even doubting if this is the correct way to access subdocuments ?
Shouldn't the subdocuments be accessed via .notation. Something like below ? (in which case I get the correct output in both the cases)
db.users.find({"user.login":"tester"});
{ "_id" : ObjectId("5773fc2826e0b6cf532569ca"), "user" : { "login" : "tester" } }
{ "_id" : ObjectId("5773fd6426e0b6cf532569cb"), "user" : { "login" : "tester", "name" : "anil" } }
and
> db.users.find({"user.name":"anil"});
{ "_id" : ObjectId("5773fd6426e0b6cf532569cb"), "user" : { "login" : "tester", "name" : "anil" } }
>
Also, based on the examples above, I am even doubting if this is the
correct way to access subdocuments ?
This is not actually. The first query, db.users.find({"user":{"login":"tester"}});, means that you're looking for a user that equals to {"login":"tester"} object completely, not a user with login field equals to tester. There is one document that matches with that criteria and that document actually returned as the query result.
Likewise, the second query, db.users.find({"user":{"name":"anil"}});, means that you're looking for a user that equals to {"name":"anil"} object completely. There is no such user. There is one document that matches with your query partially but it's not enough.
If you're looking for a user with name equals to anil, use Dot Notation to access the sub-document, as you did in your second group of queries.
Shouldn't the subdocuments be accessed via .notation. Something like
below ? (in which case I get the correct output in both the cases)
Yes. this is the correct way.

Mongodb & Symfony QueryBuilder

Does someone know where I can find some informations about Mongodb QueryBuilder in Symfony2 please? Maybe some examples or some tutorials.
I googled the question but didn't find something good enough..
More specifically I want to retrieve a field in a document based on the embedded document.
Here is an example of document :
{
"name":"Foo",
"age":"25",
"gender":"Male",
"products":[
{
"name":"Apple",
"price":"12.00",
"date":"2015-12-02"
},
{
"name":"Banana",
"price":"9.00",
"date":"201-11-31"
},
]
}
And I want to retrieve the name "Foo" based on the date in products array.
At the moment I use distinct() to list all fields in products.
Simple doctrine mongodb example for EmbedMany in symfony
Assume that a League may have one or many Teams so it is a Embed Many like in your case. Full example is above. If you want more info then I think first 5 posts are enough for you.
EXAMPLE USAGE
->findOneByProperty('name', 'Premiership')
REPO
use Doctrine\ODM\MongoDB\DocumentRepository;
class LeagueRepository extends DocumentRepository
{
/**
* #param string $field
* #param string $data
*
* #return array|null|object
*/
public function findOneByProperty($field, $data)
{
return
$this->createQueryBuilder('League')
->field($field)->equals($data)
->getQuery()
->getSingleResult();
}
}
DUMMY DATA
db.getCollection('league').find({})
/* 1 */
{
"_id" : ObjectId("564fa07add576ebcf90041ac"),
"name" : "Super Lig",
"createdAt" : ISODate("2015-11-20T22:36:42.000Z")
}
/* 2 */
{
"_id" : ObjectId("564fa081dd576ebbf90041ad"),
"name" : "Premiership",
"createdAt" : ISODate("2015-11-20T22:36:49.000Z"),
"updatedAt" : ISODate("2015-11-20T22:37:33.000Z"),
"teams" : [
{
"_id" : ObjectId("564fa0a6dd576ef2f80041ad"),
"name" : "Arsenal",
"createdAt" : ISODate("2015-11-20T22:37:26.000Z")
},
{
"_id" : ObjectId("564fa0addd576ebaf90041ad"),
"name" : "Liverpool",
"createdAt" : ISODate("2015-11-20T22:37:33.000Z")
}
]
}

One query to get parent of document with id

I have id of person ObjectId("5650e94b2e62c5fbfa0ebdd1"). How get name of its leader with one query?
/* 1 */
{
"_id" : ObjectId("5650e94b2e62c5fbfa0ebdd1"),
"login" : "Todd",
"fullname" : "Eva Bailey",
"leader" : ObjectId("5650e94b2e62c5fbfa0ebdd2"),
"group" : ObjectId("5650e94b2e62c5fbfa0ebdbf")
}
/* 2 */
{
"_id" : ObjectId("5650e94b2e62c5fbfa0ebdd2"),
"login" : "Kennedy",
"fullname" : "Oscar Stokes",
"leader" : null,
"group" : ObjectId("5650e94b2e62c5fbfa0ebdbf")
}
MongoDB is non relational database and does not support joins as opposed to other relational DB which defines relationship through reference keys across tables in database.
Instead of defining references of documents across collections in MongoDB you can utilize embedded document feature of MongoDB.
Embedded documents are easy and fast
Example :
{
"_id" : ObjectId("5650e94b2e62c5fbfa0ebdd1"),
"login" : "Todd",
"fullname" : "Eva Bailey",
"leader" :
{
"name":"Tony Smith"
},
"group" : {
}
}