PyMongo does not iterate collection

I have strange behavior in Python / PyMongo.

dbh = self.__connection__['test'] first = dbh['test_1'] second = dbh['test_2'] first_collection_records=first.find() second_collection_records=second.find() index_f=first_collection_records.count() //20 index_s=second_collection_records.count() //120 i=0 for f in first_collection_records: for s in second_collection_records: i=i+1 print i 

and it prints only 120 times (1..120), not 20x120 times. Can someone tell me why he is not sorting the external collection? I printed the results; it always takes only the first of the external and iterations over the internal collection. (I sent the counts that I get in code 20 and 120, I tried with xrange and fetch by index, but nothing)

+4
source share
1 answer

If you want to iterate second_collection_records for each first_collection_records, you can use:

 i=0 for f in first_collection_records: second_collection_records.rewind() #Reset second_collection_records iterator for s in second_collection_records: i=i+1 print i 

. return () resets the cursor to a new state, allowing you to retrieve data in second_collection_records again.


Explanation:

 second.find() 

returns a Cursor object containing an iterator.

When the cursor iterator reaches its end, it returns nothing more.

in the following way:

 for f in first_collection_records: #20 

actually iterates 20 times, but since internal:

 for s in second_collection_records: 

already repeated all returned objects, the second time it is called, second_collection_records does not return anything else, so the code inside (i = i + 1, print ...) is not executed.

You can try this as follows:

 i = 0 for f in first_collection_records: print "in f" for s in second_collection_records: print "inside s" 

You will get the result:

 inside f inside s inside s ... inside s inside f <- since s has nothing left to be iterated, (second_collection_records actually raised StopIteration such in generator), code inside for s in second_collection_records: is no longer executed inside f inside f 

Detailed explanation:

This line:

 for s in second_collection_records: 

the loop here actually works with the next () method of the Cursor object, as in: calling second_collection_records.next () until the second_collection_records raised a StopIteration exception (it is caught in the Python generator and for the StopIteration loop, and the code inside the loop will not be executed). So in the second last loop of first_collection_records, second_collection_records.next () actually raised StopIteration for the inner loop without executing code.

We can easily observe this behavior by doing the following:

 for f in first_collection_records: print "inside f" second_collection_records.next() for s in second_collection_records: print "inside s" 

And the result:

 inside f inside s ... inside s inside f Traceback (most recent call last): ... , in next raise StopIteration StopIteration 
+8
source

Source: https://habr.com/ru/post/911677/


All Articles