This post has my problem too but no one answer that. I have a model in the mongodb with some fields in which one of them named synced which is a boolean field.
With the code below I want to update one (or with some minor changes more than one) document's "synced" field:
db.bulk_write([UpdateOne({'content_id': '6101-1514301051'}, {'$set': {'synced': True}})]).bulk_api_result
But the result says that one matched doc found with no update:
{'writeErrors': [],
'writeConcernErrors': [],
'nInserted': 0,
'nUpserted': 0,
'nMatched': 1,
'nModified': 0,
'nRemoved': 0,
'upserted': []}
And when I do the same only with another field I get the right answer and the update successfully applied:
db.bulk_write([UpdateOne({'content_id': '6101-1514301051'}, {'$set': {'visit': 14201}})]).bulk_api_result
{'writeErrors': [],
'writeConcernErrors': [],
'nInserted': 0,
'nUpserted': 0,
'nMatched': 1,
'nModified': 1,
'nRemoved': 0,
'upserted': []}
What is wrong with my code and how can I apply the changes to the synced filed?
MORE INFO:
I also do the same thing with mongo-shell:
> db.my_model_name.updateOne({"content_id": "6101-1514301051"}, {$set: {"synced": true}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 0 }
or with
> db.telegram_post_model.update({"content_id": "6101-1514301051"}, {$set: {"synced": true}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
But still cannot update the document.
Following code works good for me:
from pymongo import MongoClient
db = MongoClient("mongodb://login:password#server:port/database_name").get_default_database()
db.telegram_post_model.update({"content_id": "6101-1514301051"}, {"$set": {"synced": True}})
Related
I'm running into an issue with Cosmos DB where the behavior of a query with {upsert: true} and $setOnInsert where the insert values are applied every time regardless of if the operation was an insert or an update.
The results of the following example query when ran against Cosmos DB and MongoDB show a difference in the final value of defaultQty.
db.products.remove({})
// WriteResult({ "nRemoved" : 1 })
db.products.insert({ _id: 1, item: "apple", price: 0.05, defaultQty: 50})
// WriteResult({ "nInserted" : 1 })
db.products.find({})
// { "_id" : 1, "item" : "apple", "price" : 0.05, "defaultQty" : 50 }
sleep(100)
db.products.update(
{ _id: 1 },
{ $set: { price: 0.10 }, $setOnInsert: { defaultQty: 100 }},
{ upsert: true }
)
// WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
db.products.find({})
// { "_id" : 1, "item" : "apple", "price" : 0.1, "defaultQty" : 100 }
Here is a screen shot of the comparison results side-by-side in Studio 3T.
Has anyone experienced this?
Thanks!
This issue is now fixed awaiting deployment. You can track progress here https://feedback.azure.com/forums/599059-azure-cosmos-db-mongodb-api/suggestions/20017141-bug-fix-during-upsert-operation-setoninsert-is-b
We Will post update once deployment is completed.
thanks!
Yes, this is a known issue that will be fixed shortly in Azure Cosmos DB.
The first answer google returned is: How do I remove a field completely from Mongo?
And the documentation: https://docs.mongodb.com/manual/reference/operator/update/unset/
I tried:
db.amazon_rev.update({}, {$unset: {'meta.asin': true}}, false, true)
db.amazon_rev.update({}, {$unset: {'meta.asin':1}}, false, true)
db.amazon_rev.update({}, {$unset: {'meta.asin': ''}}, false, true)
db.amazon_rev.update({}, {$unset: {'meta.asin': ''}}, {multi: true})
db.amazon_rev.update({}, {$unset: {'meta.asin':1}}, {multi: true})
db.amazon_rev.update({}, {$unset: {'meta.asin': true}}, {multi: true})
Every time it says:
WriteResult({ "nMatched" : 237199, "nUpserted" : 0, "nModified" : 0 })
and nothing changed:
(This collection was merged together from two collections (review and meta, both indexed by asin) by mongodb aggregation $lookup)
db.amazon_rev.findOne()
{
"_id" : ObjectId("57f21916672286a104572738"),
"reviewerID" : "A2E2I6B878????",
"asin" : "B000GI????",
"reviewerName" : "Big????",
"helpful" : [
0,
0
],
"unixReviewTime" : 137???????,
"reviewText" : "........................................",
"overall" : 5,
"reviewTime" : "????, 2013",
"summary" : "............",
"meta" : [
{
"_id" : ObjectId("57f218e2672286a10456af7d"),
"asin" : "B000GI????",
"categories" : [
[
".................."
]
]
}
]
}
Is there something I missed? Thanks for any suggestion!
Can try using positional operator $ and check that field exist or not using $exists. this process only unset the first element of an array.
db.amazon_rev.update({
"meta.asin": {$exists: true}
},{
$unset: {
"meta.$.asin" : true
}
},false,true);
if you want to delete each asin from meta array then better process is find documents and remove each meta.asin then save again that document.
I'm completely new to NoSQL databases and I'm working currently with MongoDB.
I'm trying to understand why the default _id index does not throw an error, when upserting a duplicate _id document.
As stated in the docs _id is an unique index by default
(although it doesn't show the unique flag here..)
> db.foo.getIndexes();
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.foo"
}
]
>
So when upserting the document (started with an empty collection),
if first inserts it and then seems to "ignore" it.
> db.foo.update({ _id: 'doe123'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true});
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "doe123" })
> db.foo.update({ _id: 'doe123'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
So I've tried another thing and created an unique index on "name".
The result of upserting a duplicate name:
> db.foo.update({ _id: 'foo456'}, { _id: 'foo456', name: 'John Doe'}, { upsert: true});
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.foo index: name_1 dup key: { : \"John Doe\" }"
}
})
Why am I not getting this kind of error on a duplicate _id?
EDIT: I'm using MongoDB v.3.2.3
There is no reason to show duplicate index error in the first case as it is just trying to update the _id and name fields of the same record with the same value.
If you will try
db.foo.update({ _id: '1098'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true});
you will get error, as query is trying to update record with different _id with some existing _id value.
In second case, you created a record first with name field and then you are trying update the same name in another record, which will give error as name is unique index.
Edit :-
If you are trying
db.foo.insert({ _id: 'doe123', name: 'John Doe'});
will give you the error, as in this case you are trying to insert a record which is already present i.e. _id is unique and you are trying to create one more record with same _id value.
upsert:true :- if upsert is true and no document matches the query criteria, update() inserts a single document.
If upsert is true and there are documents that match the query criteria, update() performs an update.
If I have the following collection
{ "_id" : "a" }
{ "_id" : "b" }
{ "_id" : "c" }
Normal query
If I now run the following query
db.test.find({_id: "a"}, {_id: 1}).explain("executionStats")
It returns
"executionStats" : {
"totalKeysExamined" : 1,
"totalDocsExamined" : 1
}
Query with hint
Now for the strange part. If I run the following query
db.test.find({_id: "a"}, {_id: 1}).hint({_id: 1}).explain("executionStats")
It returns
"executionStats" : {
"totalKeysExamined" : 1,
"totalDocsExamined" : 0
}
Question
Why is the normal query examining a document, even if I only want the _id?
Server version: v3.2.1
What you are doing is that you are generally using the _id index instead of going through the collection. You get to see the indexes using
collection.getIndexes()
In that sense the mongo server (query optimizer) used the index specified (_id) and did not have to go through the collection
Hop that helps
I have a document in a mongodb collection like this :
{
sessions : [
{
issues : [
{
id : "6e184c73-2926-46e9-a6fd-357b55986a28",
text : "some text"
},
{
id : "588f4547-3169-4c39-ab94-8c77a02a1774",
text : "other text"
}
]
}
]
}
And I want to update the issue with the id 588f4547-3169-4c39-ab94-8c77a02a1774 in the first session.
The problem is that I only know that it's the first session and the issue id (NOT the index of the issue !)
So I try something like this :
db.mycollection.update({ "sessions.0.issues.id" : "588f4547-3169-4c39-ab94-8c77a02a1774"},
{ $set: { "sessions.0.issues.$.text" : "a new text" }})
But I got the following result :
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 16837,
"errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: sessions.0.issues.$.text"
}
How can I do this ?
Thanks for help.
You have to use this (apparently equivalent) query:
db.mycollection.update({"sessions.0.issues": {$elemMatch: {id: <yourValue>}}}, {$set: {"sessions.0.issues.$.text": "newText"}})
Notice that your update expression was correct.
More information about $elemMatch.
Btw, MongoDB reference explicits that $ operator does not work "with queries that traverse nested arrays".
Important: $elemMatch only works with version 4 or more.