how do I sort using find_one

3,297 views
Skip to first unread message

J.E. Turcotte

unread,
Nov 26, 2010, 6:23:39 PM11/26/10
to mongod...@googlegroups.com
Apologies right up front for being relatively green at python and even greener with mongodb, but after having killed an entire day trying to find any documentation or actual working example of this (and stressing out my poor girlfriend this whole time), I'm just going to hit you guys up:

I have a small db called 'jetblog' inside of which is a small collection 'entry.'  Entry has '_id', 'title', 'post', 'edits {'editor', 'email', 'written'}', 'category', and 'zone.'

using pymongo, all I want is to get the ONE most recently edited (i.e., entry.edits.written) entry.  The documentation doesn't give any example for find_one() beyond ().  It doesn't want to take .sort(), and I'm not having any luck translating [

find([spec=None[, fields=None[, skip=0[, limit=0[, timeout=True[, snapshot=False[, tailable=False[, sort=None[, max_scan=None[, as_class=None[, **kwargs]]]]]]]]]]])  >>> db.test.find({"hello": "world"}) ??

] into a python example without a similar (and seemingly impossible to find) example of someone else doing similar.  How does this definition translate into a line of python|pymongo code?  I don't want to limit the search by any fields and values, I just one 1 return, and that it be the most recent entry.edits.written value in the collection...

Sorry, I just haven't seen enough thorough examples of find() or find_one() that can make the above definition syntax translate in my head.  =(  I would never have guessed such a simple query would be so hair-whitening.

~jet

Dwight Merriman

unread,
Nov 26, 2010, 7:06:33 PM11/26/10
to mongod...@googlegroups.com
i don't know python but in the mongo shell one would do 

> use jetblog
> db.entry.find().sort( { "edits.written" : -1 } ).limit(1).next()

as findOne() doesn't take a short param.  

i.e., find(...).limit(1) (then deferencing the returned cursor) is the same as findOne basically.

maybe someone else can chime in on the appropriate PyMongo lingo

--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.

Scott Hernandez

unread,
Nov 26, 2010, 7:07:19 PM11/26/10
to mongod...@googlegroups.com
findOne(...) is synonymous for find(...).limit(1); internally it just
asks for limit of 1, and then returns that first one.

Scott Hernandez

unread,
Nov 26, 2010, 7:12:32 PM11/26/10
to mongod...@googlegroups.com
Here is the actual code:
http://github.com/mongodb/mongo-python-driver/blob/master/pymongo/collection.py#L469

Note: A negative limit tell the server to return that number (or what
fits in a response), and closes the cursor immediately.

J.E. Turcotte

unread,
Nov 26, 2010, 7:46:22 PM11/26/10
to mongod...@googlegroups.com
Aye, that's essentially word for word what's on the api documentation
site. I can see that it somehow offers me sort as an internal spec, but
there's no example given as to how to properly lay out these optional
specs syntactically... especially when the definition is suggesting that
its a list within a list within a list within a list within a list
within a list within a list before I even get to the sort option. (I am
reading it wrong of course, but that is the crux of my request for
help!) I've no rosetta stone on this one.

I have the following:
-------------
for entries in blog.entry.find().sort("edits.written", pymongo.DESCENDING):
print entries['title']

entry = blog.entry.find_one().sort("edits.written")
print entry
-------------
I get:
-------------
[________@_____ www]$ python test.py
So, this is the first real post on my new blog...
30 Days of Writing
30 Days of Writing, Day 1
30 Days of Writing, Day 2
30 Days of Writing, Day 3
30 Days of Writing, Day 4
Potential Web Development Contracting
30 Days of Writing, Day 5
30 Days of Writing, Day 6
30 Days of Writing, Day 7
30 Days of Writing, Day 8
30 Days of Writing, Day 9
What's up with that, NASA?
30 Days of Writing, Day 10
30 Days of Writing, Day 11
30 Days of Writing, Day 12
30 Days of Writing, Day 13
30 Days of Writing, Day 14
30 Days of Writing, Day 15
Switching over to MongoDB
Traceback (most recent call last):
File "test.py", line 12, in <module>
entry = blog.entry.find_one().sort("edits.written")
AttributeError: 'dict' object has no attribute 'sort'
-------------

... now, oddly... when i do pymongo.ASCENDING or DESCENDING on another
field (category or zone for example) they correctly reverse directions.
However, if I use it on the datetime field there, it pretends to work,
but they're always in ascending order either way. That's another
question, I suppose.

for now, though, find_one() appears to have dereferenced the sole
result, by which point it is too late to sort on it. So it seems I need
to have a means of doing the sort within the (), and I've not had any
success finding an example of that for either .find() or .find_one().
*fail*

Taking a hint from Dwight Merriman's mongo command line version:
-------------
for entries in blog.entry.find().sort("edits.written",
pymongo.DESCENDING).limit(1):
print entries['title']
-------------
I do get a sole result, but it's still ignoring the sort when sorting
against a date. =( I know I'll eventually want to create an index on
that field of that subdocument (gee, I hope I can, come to think of it);
setting it to descending may force this the other way? (i shall
experiment, since I've already had to un-port to do my daily blogging
which means a new re-port tomorrow for hair-whitening exercises.)

~jet


--
LEGAL NOTICE: The information in this transmission may contain privileged and confidential information. It is intended only for the use of the person(s) named above. If you are the intended recipient, you are hereby notified that any review, dissemination, distribution, or duplication of this communication is strictly prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.

Reply all
Reply to author
Forward
0 new messages