pymongo+MongoDB: How to find _id in pymongo? - python

I want to find the _id of a document of a collection (mycol) where "name":"John". I have inserted the document but want to find the _id of document. Is it possible ? I am trying as
result = db.mycol.find({"_id": {"name": "John"}})
But it is returning a cursor object.
pymongo.cursor.Cursor object at 0x00000000030E3DD8>
Then I tried as
for itm in result:
print (itm)
But it is not printing anything.

Try it like that
result = db.mycol.find({"name": "John"})
for item in result:
print(item['_id'])
Just have a look at the docs to see how to use pymongo

Related

How get Id when do upsert with flask_pymongo?

I want to get the document id, when I do and upsert, currently flask-pymongo only returns object Id when the document is inserted but not when is updated.
I am using the following code:
a = mongo.db.abcd.update_one(
{'abcd': 'abcd1'}, {"$set": {"abcd": "abcd2"}}, upsert=True)
for value in a.raw_result.items():
print(value)
There are any way to return the id?
Thanks
update_one() returns a instance of UpdateResult (https://pymongo.readthedocs.io/en/stable/api/pymongo/collection.html#pymongo.collection.Collection.update_one) and UpdateResult have a property upserted_id.
The documentation say: The _id of the inserted document if an upsert took place. Otherwise None.
https://pymongo.readthedocs.io/en/stable/api/pymongo/results.html#pymongo.results.UpdateResult.upserted_id
Looks like that is what you need

solve E11000 duplicate key error collection: _id_ dup key in pymongo

I am trying to insert a great number of document(+1M) using a bulk_write instruction. In order to do that, I create a list of InsertOne function.
python version = 3.7.4
pymongo version = 3.8.0
Document creation:
document = {
'dictionary': ObjectId(dictionary_id),
'price': price,
'source': source,
'promo': promo,
'date': now_utc,
'updatedAt': now_utc,
'createdAt:': now_utc
}
# add line to debug
if '_id' in document.keys():
print(document)
return document
I create the full list of document by adding a new field from a list of elements and create the query by using InsertOne
bulk = []
for element in list_elements:
for document in documents:
document['new_field'] = element
# add line to debug
if '_id' in document.keys():
print(document)
insert = InsertOne(document)
bulk.append(insert)
return bulk
I do the insert by using bulk_write command
collection.bulk_write(bulk, ordered=False)
I attach the documentation https://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.bulk_write
According to the documentation,the _id field is added automatically
Parameter - document: The document to insert. If the document is missing an _id field one will be added.
And somehow it seems that is doing it wrong because some of them have the same value.
Receiving this error(with differents _id of course) for 700k of the 1M documents
'E11000 duplicate key error collection: database.collection index: _id_ dup key: { _id: ObjectId(\'5f5fccb4b6f2a4ede9f6df62\') }'
Seems a bug to me from pymongo, because I used this approach in many situations but I didn't with such size of documents
The _id field has to be unique for sure, but, due to this is done automatically by pymongo, I don't know how to approach to this problem, perhaps using a UpdateOne with upsert True with an impossible filter and hope for the best.
I would appreciate any solution or work around for this problem
It seems that as I was adding the new field of the document and append it into the list, I created similar instances of the same element, so I had the same queries len(list_elements) times and that is why I had the duplicated key error.
to solve the problem, I append to the list a copy of the document
bulk.append(document.copy())
and then create the queries with that list
I would like to thank #Belly Buster for his help in the issue
If any of the documents from your code snippet already contain an _id, a new one won't be added, and you run the risk of getting a duplicate error as you have observed.

How to access the value of one atribute in pymogo

I am new to pymongo and mongo db and created a cluster with the database and the collection I need. I have added data to the Collection but i'm having trouble retrieving the data as individual values. I need to find the only record where the Gender is female and check the Name belonging to that record, Not been able to find help online. Sorry if it's a noob question
import pymongo
client = pymongo.MongoClient('mongodb+srv://#test-v6kig.mongodb.net/admin')
testdb = client['mytestdb']
testcol = testdb['mytestcol']
myquery = { "Gender" : "Female" }
data = testcol.find(myquery)
if "Need to get value of NAME attribute in the data record" == "Sushmit":
print("Y")
else:
print("N")
Any help is appreciated :)
use find_one methods and pass to it the id parameter like this:
single_value= testcol.find_one({'id'})
find_one always returns a single result which is a JSON document. find always returns a cursor (even if there is only a single result or no results). So to get the results from your find query you would do:
cursor=pymongo.find(myquery)
for doc in cursor:
print(doc)

how to update entire object without changing the id in pymongo?

I am trying to update all properties of the record/object which is stored in MongoDB, now I am trying to do like this.
Deleted the object, but keeping the ID of the object being deleted.
Create a new object with the same ID which I have deleted.
Is it correct ? or What is they to do above objective using pymongo ?
mongo_object = {
_id : 123,
prop_key_1: some_value,
// ... many present
prop_key_n: some_value,
}
def delete(record):
doc = get_db().reviews.delete_many({"id" : record["_id"]})
print(doc.deleted_count)
# all key values are changed, mongo_object is changed except the id.
delete(mongo_object)
db.collection_name.insert_one(mongo_object)
But above code is not deleting the object, the doc.deleted_count is 0.
db.collection_name.update_one({"_id" : record["_id"]}, new_data}
just use update without $set , the document will get replaced completely without changing the _id
from bson.objectid import ObjectId
def replace_one(record):
result = client.test_db.test_collection.replace_one({"_id":ObjectId(record["_id"])}, record,upsert=True)
print(result.matched_count)
What is the correct way to query MongoDB for _id using string by using Python?
Pymongo doc - http://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.replace_one

What is the proper way to check if a document in mongodb with find().limit()?

for hashtag in hashtags:
existing_hashtag = hashtags_collection.find({"string": hashtag}).limit(1)
if existing_hashtag:
hashtags_collection.update({"string": hashtag},
{"$inc": {"popularity": 1}})
else:
new_hashtag = {"string": hashtag,
"popularity": 1}
hashtags_collection.insert_one(new_hashtag)
find_one will return actual object but I heard that it is not efficient. find + limit only returns a cursor object even if it doesn't find a match. So how can I implement find + limit in mongodb?
First of all, don't issue a query for each element in your iterable here "hashtags" instead, you should use the $in query operator.
That being said, you can use the count method to check whether or not any document in your collection "string"'s value is your array.
collection.count({"string": {"$in": hashtags}})
Last and not least, you don't need the if/else statement here, simply let MongoDB do the job for you by using bulk operation and the upsert option.
In conclusion you code should look like this.
from pymongo import UpdateOne
bulk_operations = [UpdateOne({'string': value}, {'$inc': {'popularity': 1 }}, upsert=True)
for value in hashtags]
hashtags_collection.bulk_write(bulk_operations)

Categories

Resources