Update same field in different documents with different value at once with MongoDB - python-3.x

I didn't found a question similar to mine and i'm not sure it's possible. I have several documents, each document is a person, for example :
{
"name" = "Paul",
"score" = 105
}
{
"name" = "John",
"score" = 98
}
Before the update i have a dict (in python) with the name and the new score {"Paul": 107, "John": 92}. How do i update the score in all the documents from the dict in one request ?

You can not update multiple documents with different conditions in a single query. You can refer MongoDB update doc. MongoDB introduced a new parameter as multi but it has a different meaning. update query with param { multi: true } will update multiple documents only which will match the same condition which we set in query part.
Optionally you can update multiple documents with loop through your query. This feature is still missing in MongoDB so we are also doing such thing in the same way.

Related

How to query field exist some document in firebase

I using firebase, nodejs and i have a question how to query field exist some document.
Example :
Collections : users => document : A with field {
....
is_correct: true
}
document : B with field {
.....
}
In my above example , i have two document in collection users. On document A i have field is_correct: true and on document B field is_correct not exist.
My collection users about 15.000 document and it have 50 document contain field is_correct: true
When i write code look like :
await firestore.collection('users').where('is_correct', '==', true).get();
it can get correct me 50 document. But i don't understand it can using index on field is_correct or not ? And it can query best performance ? I understand firebase can't get document if field undefined. It impart in case ? Please help ? Thanks you
For a simple query like
firestore.collection('users').where('is_correct', '==', true)
you don't need to configure any index, Firestore does it automatically.
As you mentioned, only documents where the given field exists can match the query.
And this is the case also for Not-equal (!=) and not-in queries: they exclude documents where the given field does not exist, as explained in the documentation.
Also, note that a field exists when it's set to any value, including an empty string (""), null, and NaN (not a number).
So, in conclusion, if you want to query for documents where is_correct is not true, you need to create this field in these documents with a value different than true.

How to sort documents in MongoDB based on keys inside a dictionary in document using MongoEngine Python?

So I have documents of this type in my MongoDB Collection:
{
"_id" : ObjectId("606c66c875a2fe6153bfc71f"),
"t_id" : "12345678a",
"r_id" : "r12345678a",
"t_e_stats" : {
"acc" : "70"
},
"register_time" : ISODate("2021-04-06T19:18:56.890Z")
}
There are multiple of these documents with same 't_id' and different 't_e_stats' dictionary. But all 't_e_stats' dictionary have 'acc' key in them. Now I want to query the entry for a particular 't_id' with the maximum value of 'acc' in the 't_e_stats' dictionary. How do I do that in MongoEngine? Or I have found there are ways to run PyMongo queries in MongoEngine also, how to use that too if possible?
As commented by OP
Model.objects(t_id="12345678a").order_by("-t_e_stats.acc").first()
if anyone is interested in not only the object but also the JSON document, then you can do this:
[data_entry._data for data_entry in Model.objects(t_id="12345678a").order_by("-t_e_stats.acc")][0]
Use .sort
https://pymongo.readthedocs.io/en/stable/api/pymongo/collection.html?highlight=find%20one#pymongo.collection.Collection.find_one
mycol.find_one({ "t_id" : "12345678a" }).sort("t_e_stats.acc", pymongo.DESCENDING)
This will return 1st record where t_e_stats.acc is max.
mongo shell
db.collection.find({ "t_id" : "12345678a" }).sort("t_e_stats.acc", -1).limit(1);
Mongoengine
Model.objects.get(t_id="12345678a").order_by("-t_e_stats.acc").first()

Firestore set doc with merge option true or update doc

I have to update a single field in an existed Firestore document.
However, I don't know if there is some difference between using
admin.firestore().doc('doc_id').set({name:'Bill'},{ merge: true })
or
admin.firestore().doc('doc_id').update({name:'Bill'})
If the document is:
{
name: Bart,
age: 18
}
Should .update(...) just update the field and not remove the field "age" in this case?
There is no difference between those two options for existing documents.
The difference between them is only evident for documents that don't exist. set() with merge will create the document if it does't exist, and update() will fail if it doesn't exist.

How to Match the string from collection after lookup with many collection using mongodb

Here My query
model.db.aggregate([{$lookup: {from: 'orders', localField: 'prod_id',
foreignField: '_id', as: 'Col'}},{$match:{$text:
{$search:'Sale'}}}).exec((err,data) => {console.log(data);}]);
but error showing "$match with $text is only allowed as the first pipeline !!"
I just want to lookup many collection then only I have to match'Search' in all the data what we joined(lookup) before.
mongoDb version: 4.0
Anybody have an idea ? need Help !
Thanks !!
These all are my Example collections:
collection 1 ->
organization ={'_id':ObjectId("5b110a7b84a0442030a1e9cf"),'Org_name':'dhoni institute','Estd':'1945'}
collection 2 -> players= {'_id':ObjectId("45110a7b84a3542030a1e9cf"),'_name':'Ms dhoni','Org_id' = ObjectId("5b110a7b84a0442030a1e9cf") }
I am searching the text string 'dhoni' in Db..then I want all the documents which contains word 'dhoni' from these collections.
How to do ?
db.players.aggregate([{$match:{$text:{$search:'dhoni'}}},
{
$lookup{from:'organization',localField:'_id',foreignField:'Org_id',as:'org'}
}
]).exec((err,data) => {}
this is my code It only matches the string from 'players' collection .I need matched 'players' collection documents as well as 'Organization' collection documents.
I cannot create new collection because after loopup data may be a huge data so
I cannot inserting new large data every time search
How to match the string after lookup ?
As explained in official mongodb documentation,
$text performs a text search on the content of the fields indexed with a text index.
But indexes are reachable only by the first stage of an aggregation query. That's the reason of your error message.
The only way i see for you to use $text/$search is to perform your aggregation (without match stage), adding an $out stage to output to a new collection, create a text index on that collection, and perform your find query with $text/$search criteria.
Hope it helps.

How do I keep existing data in couchbase and only update the new data without overwriting

So, say I have created some records/documents under a bucket and the user updates only one column out of 10 in the RDBMS, so I am trying to send only that one columns data and update it in couchbase. But the problem is that couchbase is overwriting the entire record and putting NULL`s for the rest of the columns.
One approach is to copy all the data from the exisiting record after fetching it from Cbase, and then overwriting the new column while copying the data from the old one. But that doesn`t look like a optimal approach
Any suggestions?
You can use N1QL update Statments google for Couchbase N1QL
UPDATE replaces a document that already exists with updated values.
update:
UPDATE keyspace-ref [use-keys-clause] [set-clause] [unset-clause] [where-clause] [limit-clause] [returning-clause]
set-clause:
SET path = expression [update-for] [ , path = expression [update-for] ]*
update-for:
FOR variable (IN | WITHIN) path (, variable (IN | WITHIN) path)* [WHEN condition ] END
unset-clause:
UNSET path [update-for] (, path [ update-for ])*
keyspace-ref: Specifies the keyspace for which to update the document.
You can add an optional namespace-name to the keyspace-name in this way:
namespace-name:keyspace-name.
use-keys-clause:Specifies the keys of the data items to be updated. Optional. Keys can be any expression.
set-clause:Specifies the value for an attribute to be changed.
unset-clause: Removes the specified attribute from the document.
update-for: The update for clause uses the FOR statement to iterate over a nested array and SET or UNSET the given attribute for every matching element in the array.
where-clause:Specifies the condition that needs to be met for data to be updated. Optional.
limit-clause:Specifies the greatest number of objects that can be updated. This clause must have a non-negative integer as its upper bound. Optional.
returning-clause:Returns the data you updated as specified in the result_expression.
RBAC Privileges
User executing the UPDATE statement must have the Query Update privilege on the target keyspace. If the statement has any clauses that needs data read, such as SELECT clause, or RETURNING clause, then Query Select privilege is also required on the keyspaces referred in the respective clauses. For more details about user roles, see Authorization.
For example,
To execute the following statement, user must have the Query Update privilege on travel-sample.
UPDATE `travel-sample` SET foo = 5
To execute the following statement, user must have the Query Update privilege on the travel-sample and Query Select privilege on beer-sample.
UPDATE `travel-sample`
SET foo = 9
WHERE city = (SELECT raw city FROM `beer-sample` WHERE type = "brewery"
To execute the following statement, user must have the Query Update privilege on `travel-sample` and Query Select privilege on `travel-sample`.
UPDATE `travel-sample`
SET city = “San Francisco”
WHERE lower(city) = "sanfrancisco"
RETURNING *
Example
The following statement changes the "type" of the product, "odwalla-juice1" to "product-juice".
UPDATE product USE KEYS "odwalla-juice1" SET type = "product-juice" RETURNING product.type
"results": [
{
"type": "product-juice"
}
]
This statement removes the "type" attribute from the "product" keyspace for the document with the "odwalla-juice1" key.
UPDATE product USE KEYS "odwalla-juice1" UNSET type RETURNING product.*
"results": [
{
"productId": "odwalla-juice1",
"unitPrice": 5.4
}
]
This statement unsets the "gender" attribute in the "children" array for the document with the key, "dave" in the tutorial keyspace.
UPDATE tutorial t USE KEYS "dave" UNSET c.gender FOR c IN children END RETURNING t
"results": [
{
"t": {
"age": 46,
"children": [
{
"age": 17,
"fname": "Aiden"
},
{
"age": 2,
"fname": "Bill"
}
],
"email": "dave#gmail.com",
"fname": "Dave",
"hobbies": [
"golf",
"surfing"
],
"lname": "Smith",
"relation": "friend",
"title": "Mr.",
"type": "contact"
}
}
]
Starting version 4.5.1, the UPDATE statement has been improved to SET nested array elements. The FOR clause is enhanced to evaluate functions and expressions, and the new syntax supports multiple nested FOR expressions to access and update fields in nested arrays. Additional array levels are supported by chaining the FOR clauses.
Example
UPDATE default
SET i.subitems = ( ARRAY OBJECT_ADD(s, 'new', 'new_value' )
FOR s IN i.subitems END )
FOR s IN ARRAY_FLATTEN(ARRAY i.subitems
FOR i IN items END, 1) END;
If you're using structured (json) data, you need to read the existing record then update the field you want in your program's data structure and then send the record up again. You can't update individual fields in the json structure without sending it all up again. There isn't a way around this that I'm aware of.
It is indeed true, to update individual items in a JSON doc, you need to fetch the entire document and overwrite it.
We are working on adding individual item updates in the near future.

Resources