2

If I have a document like this:

{
    "_id" : ObjectId("5497b4281a78a9120872ca32"),
    "title" : "Thrifty Kitchen",
    "description" : "Damn ugly",
    "products" : [
        ObjectId("54990eeb1a78a91a5758af75"),
        ObjectId("a78a91a5758af7554990eeb1"),
        ObjectId("a5758af990eeb17554a78a91")
    ]
}

...and if (using pymongo) I want to pass this document to my webpage template, where is a good place to insert the queries to do this? I understand that I'll have to do an "$in" query to get these results, but in an ORM world I could write a method on the model class and just expose a "get_products" method. Here, since my view-logic interacts directly with Mongo and there is no ORM in the middle, what's the common practice or pattern to handle these resolutions?

result = mongo.db.mycollection.find_one({"_id": ObjectId(collection_id)})
# wish it could be
for product in result.products:
    print product.myattribute # but that will only return the ObjectId

# would you do something like this?
result.resolved_products = ... # do stuff to resolve ObjectIds

And, I haven't seen it yet in my Googling, but does anyone ever embed queries into methods of a class so that you can add functionality to the resulting objects? Sort of like using an ORM but without the schema definitions...

Scott
  • 3,204
  • 3
  • 31
  • 41

1 Answers1

3

As you expect, the answer with PyMongo is simply:

resolved_products = list(mycollection.find({'_id': {'$in': result['products']}}))

MongoEngine and other MongoDB ODMs provide helper methods to do this kind of dereferencing. But they come with their own complexity and overhead; I prefer to query directly for the related documents, as I showed.

A. Jesse Jiryu Davis
  • 23,641
  • 4
  • 57
  • 70
  • Thank you for giving the example. Regarding my question about wrapper classes, I suppose there are probably those that "roll their own", but ODMs probably bear the brunt of that need. Personally, I like the simplicity of querying directly too. Thanks again! – Scott Dec 25 '14 at 06:55