How do I find a document using Mongolab's $oid with pymongo? - mongodb

I'm trying to do this:
event = coll.find_one({"_id": {"$oid": event_id}})
Where event_id is the string from an ObjectId:
event_id='50bbd48eefbdd2a1e83bc440'
but the event ends up empty. I'm certain this is not how you find documents with the ObjectId's in pymongo, but I have searched for a while and have not figured out how. Any help would be appreciated. Thanks!

You have to convert event_id to an ObjectId like this:
from bson.objectid import ObjectId
event_id='50bbd48eefbdd2a1e83bc440'
event = coll.find_one({"_id": ObjectId(event_id)})

When searching by id with event_id the ObjectId string as you define it, simply do
event = coll.find_one(event_id)

Related

how to find item in mongo collection when _id is object?

I have mongo collection which have _id key as object of 2 key value pair. (_id = {"id":123, "slice":1}). how can I use pymongo find() to fetch an item using _id? sample collection item looks like this.
Use the uuid module as follows:
db.foo.drop()
import uuid
uu = uuid.uuid4()
uu2 = uuid.uuid4()
db.foo.insert_one({'_id':{'execution_id':uu, 'slice':1}, 'realm':'bar'})
print("should find it:", db.foo.find_one({'_id':{'execution_id':uu, 'slice':1}}))
print("should NOT find it:", db.foo.find_one({'_id':{'execution_id':uu2, 'slice':1}}))

Error getting MongoDB by _Id in Flask

I can query my MongoDB and I see the "_id" value like this:
"_id" : BinData(3,"sFgVQWMKzUiWl5dql62j2g==")
Using Flask 0.10.1 and PyMongo 3.0.3 I attempt to "find_one" like this:
record = db.collection.find_one({'_id': ObjectId("sFgVQWMKzUiWl5dql62j2g==")})
And I get this error:
bson.errors.InvalidId: 'sFgVQWMKzUiWl5dql62j2g==' is not a valid ObjectId, it must be a 12-byte input or a 24-character hex string
Any help would be appreciated.
Try this:
record = db.collection.find_one({'_id': BinData(3, "sFgVQWMKzUiWl5dql62j2g==")})
Ok here is how I got this working. From my PyMongo client I queried the result and got this:
_id: "497ffaf0-5ed3-3a4e-99ae-6b5c5f9b431e"
Note how that is not like the MongoDB console client which returns this:
_id : BinData(3,"sFgVQWMKzUiWl5dql62j2g==")
So seeing that the value looked like a GUID I started digging around and found that is a UUID and with that I did this:
import uuid
record = db.collection.find_one({'_id': uuid.UUID("497ffaf0-5ed3-3a4e-99ae-6b5c5f9b431e")})
This worked! Hazzah.
You are storing _id as bindata and trying to retrive it as ObjectId,
instead of ObjectId.
First you need to convert your base64string to binary and then try to search.
bi = binary.Binary("sFgVQWMKzUiWl5dql62j2g==");
record = db.collection.find_one({'_id': bi});
This will work for you.
It will convert your id to binary then compare to get result.
Using Flask, MongoEngine I also was receiving errors searching by _id: mongoengine.errors.ValidationError: "DBRef('m_turk', ObjectId('5966b478b929570647f51a5c'))" is not a valid ObjectId, it must be a 12-byte input or a 24-character hex string
In my case, the object id from MongoEngine.Document is of type bson.dbref.DBREF, whereas MongoEngine.Document expects type bson.objectid.ObjectId, despite returning bson.dbref.DBREF on MongoEngine.Document.objects(...).*. I'm not sure if this is an API inconsistency or simply my fault.
The fix was:
from flask_mongoengine import MongoEngine
from bson.objectid import ObjectId
... set Flask up ...
db = MongoEnginee(app)
class MiniFoo(db.Document):
foo = db.StringField()
class MyDoc(db.Docment):
key = db.StringField()
myself = db.ReferenceField(MiniFoo)
other_foos = db.ReferenceField(MiniFoo)
myobj = MyDoc.objects.get(key="over the rainbow")
# want to find other foos!
# Will fail with exception above
try:
MiniFoo.objects.with_id(myobj.other_foos[0].id)
except:
MiniFoo.objects.with_id(ObjectId(obj.id))
with MongoEngine
from flask_mongoengine import MongoEngine
from bson.objectid import ObjectId
db = MongoEngine()
db.init_app(app)
class Model(db.Document):
_id = db.ObjectIdField()
name = db.StringField(required=True)
#classmethod
def findById(cls, _id: str):
return cls.objects(_id=ObjectId(_id)).first()
modelById = Model.findById('601ec2d13ad7559bf7ebad76')

updating a multi-embedded data in mongodb

I want to insert into an array-list in an embedded data. I tried several ways but couldn't make it out. My data structure is something like this. The code given here is just a dummy reference to my original data structure
Class X{
Integer _id;
Arraylist<Y> objY;
}
Class Y{
Integer _id;
Arraylist<Z> objZ;
}
Class Z{
Integer _id;
String value;
String oldValue
}
I want to insert a new data into objZ
I know the id value of Class X an Y.
I am using Spring mongotemplate.
Does Spring Mongo Template Supports this?
Can someone help me out through this.
Thanks in advance.
I got it hope it might help someone out here, Use aggregetion to do this.
Query searchUserQuery = new Query((Criteria.where("_id").is("542264c8e4b098972a1cf60c").and("leads._id").is("2")));// _id is the id of class X
AggregationOperation match = Aggregation.match(searchUserQuery );
AggregationOperation group = Aggregation.group("objY");
Aggregation aggregation = Aggregation.newAggregation(Aggregation.unwind("objY"),match, group);
List<objY> asd=mongoOperation.aggregate(aggregation, "Name_of_ur_collection", B.class).getMappedResults();
ArrayList<Z> s=asd.get(0).getObjZ();
s.add("New Data to be added");
mongoOperation.updateFirst(searchUserQuery, Update.update("objY.$.objZ", s), X.class);
This will insert your array list in class Y.
Thanks

Search for ObjectId of a document: pymongo

I want to access a document in collection by 'name' attribute for getting its ObjectId so that i can insert that unique objectid to other document for reference.
cursorObject = db.collectionIngredient.find({'name': 'sugar'})
I want _id field of cursorObject.
cursorObject.'_id' or cursorObject._id not working.
I have tried __getitem__, __getattribute__ and so much internet surfing but couldn't able to find a way.
Please help
First, as #jjmartinez pointed out, find returns a cursor, which you need to iterate over, in order to get hold of the documents returned by your query. The _id field belongs to the documents, not the cursor.
I'm guessing that in your case the name is unique, so you can avoid cursor/iterating if you use find_one instead of find. Then you get the document directly.
Then, to access the _id, you just need a standard dict-item access:
id = doc['_id']
So we get:
ingredient = db.collectionIngredient.find_one({'name': 'sugar'})
if ingredient is not None:
id = ingredient['_id']
else:
id = None
When you do cursorObject = db.collectionIngredient.find({'name': 'sugar'}) you have a collection of documents, not a single element. So you need to explore all the collection. You need to iterate inside the cursor:
try:
cursorObject = db.collectionIngredient.find({'name': 'sugar'})
except:
print "Unexpected error:", sys.exc_info()[0]
for doc in cursorObject:
print doc
Here you have the Pymongo Tutorial

How to get the object id in PyMongo after an insert?

I'm doing a simple insert into Mongo...
db.notes.insert({ title: "title", details: "note details"})
After the note document is inserted, I need to get the object id immediately. The result that comes back from the insert has some basic info regarding connection and errors, but no document and field info.
I found some info about using the update() function with upsert=true, I'm just not sure if that's the right way to go, I have not yet tried it.
One of the cool things about MongoDB is that the ids are generated client side.
This means you don't even have to ask the server what the id was, because you told it what to save in the first place. Using pymongo the return value of an insert will be the object id. Check it out:
>>> import pymongo
>>> collection = pymongo.Connection()['test']['tyler']
>>> _id = collection.insert({"name": "tyler"})
>>> print _id.inserted_id
4f0b2f55096f7622f6000000
The answer from Tyler does not work for me.
Using _id.inserted_id works
>>> import pymongo
>>> collection = pymongo.Connection()['test']['tyler']
>>> _id = collection.insert({"name": "tyler"})
>>> print(_id)
<pymongo.results.InsertOneResult object at 0x0A7EABCD>
>>> print(_id.inserted_id)
5acf02400000000968ba447f
It's better to use insert_one() or insert_many() instead of insert(). Those two are for the newer version. You can use inserted_id to get the id.
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
myDB = myclient["myDB"]
userTable = myDB["Users"]
userDict={"name": "tyler"}
_id = userTable.insert_one(userDict).inserted_id
print(_id)
Or
result = userTable.insert_one(userDict)
print(result.inserted_id)
print(result.acknowledged)
If you need to use insert(), you should write like the lines below
_id = userTable.insert(userDict)
print(_id)
Newer PyMongo versions depreciate insert, and instead insert_one or insert_many should be used. These functions return a pymongo.results.InsertOneResult or pymongo.results.InsertManyResult object.
With these objects you can use the .inserted_id and .inserted_ids properties respectively to get the inserted object ids.
See this link for more info on insert_one and insert_many and this link for more info on pymongo.results.InsertOneResult.
updated; removed previous because it wasn't correct
It looks like you can also do it with db.notes.save(...), which returns the _id after it performs the insert.
See for more info:
http://api.mongodb.org/python/current/api/pymongo/collection.html
some_var = db.notes.insert({ title: "title", details: "note details"})
print(some_var.inserted_id)
You just need to assigne it to some variable:
someVar = db.notes.insert({ title: "title", details: "note details"})
To get the ID after an Insert in Python, just do like this:
doc = db.notes.insert({ title: "title", details: "note details"})
return str(doc.inserted_id) # This is to convert the ObjectID (type of doc.inserted_id into string)