update query in mongo db - mongodb

I am using mongodb database to save the records.
This is one sample record:
"_id" : ObjectId("53870ed7e4b00e612650c1b8"),
"_class" : "mkcl.os.transformer.PayloadObject",
"formId" : NumberLong(50),
"dataMap" : {
"240" : "ramanbaug",
"241" : "1234",
"242" : "12345678",
"243" : "mr.joshi",
"244" : "8308009391 ",
"245" : "anuja2487#gmail.com",
"280" : "456",
"287" : "1234",
"276" : "29/05/14",
"247" : "No",
"248" : "No",
"249" : "Yes",
"250" : "No",
"251" : "Yes",
"252" : "No"
}
Now I want to update the value of field "241". I read about the Update and FindAndModify Query. But There is no error and records are not getting updated.

db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
in the place of enter same query as you use to find that record(s), which you want to update
in the place of enter new values, like doing during insert query
and there are 3 more options:
upsert = Optional. If set to true, creates a new document when no document matches the query criteria. The default value is false, which does not insert a new document when no match is found. So if your doc will not be found you will create a new one
multi = Optional. If set to true, updates multiple documents that meet the query criteria. If set to false, updates one document. The default value is false. For additional information, see Multi Parameter.
writeConcern = Optional. A document expressing the write concern. Omit to use the default write concern.
you can read more about write concern here: http://docs.mongodb.org/manual/core/write-concern/
Single document update example:
db.people.update(
{ name: "Andy" },
{
name: "Andy",
rating: 1,
score: 1
},
{ upsert: true }
)
check out for upsert: true, so it will create new doc if none found by name=Andy
Multi documents update example:
db.books.update(
{ stock: { $lte: 10 } },
{ $set: { reorder: true } },
{ multi: true }
)
Example with your data:
db.people.update(
{ _id: ObjectId("53870ed7e4b00e612650c1b8") },
{
dataMap: {
"241": "321"
}
}
)
that should work.
It's all in official documentation:
http://docs.mongodb.org/manual/reference/method/db.collection.update/

db.payloadObject.update({"dataMap.241":'1234'},{$set :{"dataMap.241":'123456'}});

Related

mongo updateMany $set nested array when some docs do not contain the path

I have a seemingly straight forward query to update the names of like objects in a mongo doc. But it fails as not all docs have comment.. what should i be looking for in the docs get around this and update only the docs that have likes on comments?
return this.model.updateMany(
{
comments: {
$exists: true
}
},
{
$set: {
'comments.likes.$[like].actor.firstName': user.firstName,
'comments.likes.$[like].actor.lastName': user.lastName,
},
},
{
multi: true,
arrayFilters: [
{ 'like.actor.username': user.username },
],
},
);
The problem is that not all comments are liked.. so then the query complains:
WriteError: The path 'comments.likes' must exist in the document in order to apply array updates.
Full output:
WriteError: The path 'comments.likes' must exist in the document in order to apply array updates.
Details:
WriteError({
"index" : 0,
"code" : 2,
"errmsg" : "The path 'comments.likes' must exist in the document in order to apply array updates.",
"op" : {
"q" : {
"comments" : {
"$exists" : true
}
},
"u" : {
"$set" : {
"comments.likes.$[like].actor.firstName" : "GGGJOHN",
"comments.likes.$[like].actor.lastName" : "Carmichael"
}
},
"multi" : true,
"upsert" : false,
"arrayFilters" : [
{
"like.actor.username" : "john.carmichael"
}
]
}
})
WriteError#src/mongo/shell/bulk_api.js:461:48
Bulk/mergeBatchResults#src/mongo/shell/bulk_api.js:841:49
Bulk/executeBatch#src/mongo/shell/bulk_api.js:906:13
Bulk/this.execute#src/mongo/shell/bulk_api.js:1150:21
DBCollection.prototype.updateMany#src/mongo/shell/crud_api.js:655:17
#(shell):1:1
Here is an illustration of the doc in q, where comments is an array and the likes on a single comment is also an array:
what if you added
under match part of the update part query you are checking if likes attribute exists in the comments object
return this.model.updateMany(
{
"comments.likes": { // <---
$exists: true
}
},
{
$set: {
'comments.likes.$[like].actor.firstName': user.firstName,
'comments.likes.$[like].actor.lastName': user.lastName,
},
},
{
multi: true,
arrayFilters: [
{ 'like.actor.username': user.username },
],
},
);

Reg: mongo db same field update

my collection is like:
{
"_id" : ObjectId("5e2664ddd692"),
"distance" : "30F75Mg",
"UpStreamsValue" : "300mbpsx75mbps75mbps"
}
I need to add another distance column with value 30F75M, please update me how can i use below query:
db.streams.updateMany(
{
"_id" : ObjectId("5e2664ddd692"),
"distance" : "30F75Mg"
},
{
$set:{
"distance": "30F75M"
}
},
{
multi: true,
arrayFilters: [{"elem.attributeName": "hsiaDownUpStreamsValue", "elem.attributeValue": "300mbpsx75mbps"}]
}
);
You need to insert into the DB.
db.collection.insert({"distance" : "30F75M", "UpStreamsValue" : "300mbpsx75mbps" })
MongoDB will it self create an unique _id.

What's the most economical alternative to multiple positional identifiers in MongoDB?

I have a collection named authors with the following schema:
authors: {
_id,
firstName,
lastName,
posts: [
post 1: {...},
post 2: {...},
post 3: {
_id,
title,
content,
tags: [
tag 1: {...},
tag 2: {...},
tag 3: {
_id,
name,
description,
},
],
},
],
}
As can be seen, posts is an array of objects inside the authors collection. Each object inside this array, in turn, has tags, another array of objects. And each of these tags objects has three fields: _id, name, and description.
I'm trying to write a GraphQL mutation to update this name field on matching documents in the collection.
const updatedTagInAuthor = await Author
.updateMany({ 'posts.tags._id': args.newTagInfo._id },
{
$set: {
'posts.$.tags.$.name': args.newTagInfo.name,
'posts.$.tags.$.description': args.newTagInfo.description,
},
}, opts);
The above snippet obviously fails since MongoDB doesn't allow multiple positional elements ($) in a query. So is there any economical alternative to accomplish what I'm trying to do?
I tried the ArrayFilter method as MongoDB suggests:
const updatedTagInAuthor = await Author.update(
{},
{ $set: { 'posts.$[].tags.$[tag].name': args.newTagInfo.name } },
{ arrayFilters: [{ 'tag._id': args.newTagInfo._id }], multi: true }
);
But this throws the following error:
Cannot read property 'castForQuery' of undefined
Still confused!
These are the documents I'm updating with the kind of query I have given,
{"name" : "Steve","details" : [ {
"work" : [ {
"Company" : "Byjus",
"id" : 1,
"country" : "India"
},
{
"Company" : "Vodafone",
"id" : 2,
"country" : "UK"
}]
}]},{"name" : "Virat","details" : [ {
"work" : [ {
"Company" : "Byjus",
"id" : 1,
"country" : "India"
},
{
"Company" : "Verizon",
"id" : 3,
"country" : "US"
}]
}]}
QUERY:
db.getCollection('Users').update({"details": {"$elemMatch": {"work.id": 1}}}, {'$set': {'details.$[].work.$.Company': 'Boeing', 'details.$[].work.$.country': 'US'} }, {multi: true});
It's similar to what you asked right?
Try inserting those two Documents in a collection called User and try the above query in Mongo CONSOLE directly, not in GUI. Use the Query completely not just the $set method.
Try this,
Author.update({"posts": { "$elemMatch": { "tags.id": args.newTagInfo._id } }},
{'$set': {'posts.$[].tags.$.name': args.newTagInfo.name, 'posts.$[].tags.$.description': args.newTagInfo.description} },
{multi: true});

How to update if exists otherwise insert new document?

How to update if exists otherwise insert new document in javascript/node.js?
I am getting as parameter to function dictionary,if dictionary contains _id should update, otherwise insert on remote server (I have connection with remote server through mongoose and I have Person schema which I want to insert/update).
In Mongoose, you'd use Person.update per the documentation. In order to create a document if it doesn't already exist, you need to pass { upsert : true } in the options hash as it defaults to false.
i.e.
Person.update( { name : 'Ted' }, { name : 'Ted', age : 50 }, { upsert : true }, callback );
collection.update with upsert:true. See also here.
[db.collection.replaceOne(filter, replacement, options)] with upsert:true
E.g. from here:
try { db.restaurant.replaceOne(
{ "name" : "Pizza Rat's Pizzaria" },
{ "_id": 4, "name" : "Pizza Rat's Pizzaria", "Borough" : "Manhattan", "violations" : 8 },
{ upsert: true }
);
}
catch (e){ print(e); }
For python:
import pymongo
client = pymongo.MongoClient("mongodb_address")
db = client.db_name
collection = db[collection_name]
# update 'data' if 'name' exists otherwise insert new document
collection.find_one_and_update({"name": some_name},
{"$set": {"data": some_data}},
upsert=True)

Update query in MongoDB shell

In the shell, my query is:
db.checkin_4e95ae0926abe9ad28000001.update({location_city:"New York"}, {location_country: "FUDGE!"});
However, it doesn't actually update my records. It doesn't error either. When I do a db.checkin_4e95ae0926abe9ad28000001.find({location_city:"New York"}); after running this, I get all my results but the location_country has not changed:
{
"_id": ObjectId("4e970209a0290b70660009e9"),
"addedOn": ISODate("2011-10-13T15:21:45.772Z"),
"location_address1": "",
"location_city": "New York",
"location_country": "United States",
"location_latLong": {
"xLon": -74.007124,
"yLat": 40.71455
},
"location_source": "socialprofile",
"location_state": "New York",
"location_zip": ""
}
This is because in second parameter of update function you need to use $set operator to update location_country as in example below:
db.checkin_4e95ae0926abe9ad28000001.update(
{location_city:"New York"}, //find criteria
// this row contains fix with $set oper
{ $set : { location_country: "FUDGE!"}});
Here you can find a list of available update operators.
Changed in version 3.6.
Following is the syntax for update :
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
}
)
Example :
db.getCollection('products').update({},{$unset: {translate:1, qordoba_translation_version:1}}, {multi: true})
In your example :
db.checkin_4e95ae0926abe9ad28000001.update(
{location_city:"New York"}, //query
// $update query
{ $set : { location_country: "FUDGE!"}});
By default, the update() method updates a single document. Set the Multi Parameter to update all documents that match the query criteria.
Example 2 :
db.checkin_4e95ae0926abe9ad28000001.update(
{location_city:"New York"}, //query
// $update query
{ $set : { location_country: "FUDGE!"}}, {multi: true});
db.m_country.update(
{"countryId": "962a0935-bf3d-4f63-a53c-254760273ede"},
{$set: {'countryPopulation': '12540000'}})
Before Update
> db.student.find({name:"Venky"}).pretty();
{
"_id" : ObjectId("6012e64dc2979ddffe1e5df9"),
"name" : "Venky",
"dept" : "MCA",
"age" : "26",
"phone" : "89786465"
}
Update Command
> db.student.update({name:"Venky"},{$set: {name:"DODDANNA CHAWAN",dept:"MCA(CS)", age:"25", phone:"1234567890"}});
Find Command See Result
> db.student.find({name:"DODDANNA CHAWAN"}).pretty();
After Updated Result
{
"_id" : ObjectId("6012e64dc2979ddffe1e5df9"),
"name" : "DODDANNA CHAWAN",
"dept" : "MCA(CS)",
"age" : "25",
"phone" : "1234567890"
}
in real life use unique "_id" to match the document becuase names will found as duplicates