0

I am writing a script where I need to fetch data from mongodb using python. I need to first sort data in descending order using timestamp field and take latest 100 documents and then again I need to sort those 100 documents based on using other fields (pin_code and timestamp). Here is the code:

cursor = db.col.find().sort([("timestamp", pymongo.DESCENDING)]).limit(100)
cus = cursor.sort([("pin_code", pymongo.ASCENDING),("timestamp",pymongo.DESCENDING)])

I am expecting that second cursor should return sorted data from first cusor but its NOT returning the expected result. I know mongodb find() and sort() function return cursor but can i use that cursor as an input to other cursor?

PS: I am using pymongo module

2
  • Can you explain what you are expecting and how this differs to what you are seeing. Commented Nov 3, 2019 at 23:14
  • Also please post example documents and what you have tried so far. Commented Nov 4, 2019 at 0:24

2 Answers 2

1

The issue you have is that you can't compound multiple sorts (or, for that matter, limits) on the cursor object; only the last method call will have any effect. We can demonstrate this with this code:

from pymongo import MongoClient, DESCENDING, ASCENDING
import datetime

db = MongoClient()['mydatabase']

db.testcollection.delete_many({})
for i in range (0, 1000):
    db.testcollection.insert({'timestamp': datetime.datetime.now(), 'pin_code': i})

cursor = db.testcollection.find().sort([("timestamp", DESCENDING)]).limit(50)
cursor.limit(200)
cursor.limit(100)
cursor.limit(150)
print(len(list(cursor)))

Gives:

150

So what you need to do is use an aggregation pipeline, or something like this, with a single sort/filter and then use sort or sorted on the results:

from pymongo import MongoClient, DESCENDING
import datetime

db = MongoClient()['mydatabase']

db.testcollection.delete_many({})
for i in range (0, 1000):
    db.testcollection.insert({'timestamp': datetime.datetime.now(), 'pin_code': i})

my_list = list(db.testcollection.find().sort([("timestamp", DESCENDING)]).limit(100))
my_list = sorted(my_list, key = lambda x: x['timestamp'], reverse=True)
my_list = sorted(my_list, key = lambda x: x['pin_code'])
for item in my_list:
    print (item)
Sign up to request clarification or add additional context in comments.

Comments

0

The find methods return a cursor, which is a reference to the result set of a query.

cursor.py

#!/usr/bin/python3

from pymongo import MongoClient

client = MongoClient('mongodb://localhost:27017/')

with client:

    db = client.testdb

    cars = db.cars.find()

    print(cars.next())
    print(cars.next())
    print(cars.next())

    cars.rewind()

    print(cars.next())
    print(cars.next())
    print(cars.next())    

    print(list(cars))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.