casbah cursor and toList

2019-08-03 05:51发布

问题:

I have a cursor in casbah, returned from a query. If I iterate over the cursor I get a certain number of results, x. If I execute the same query and do a toList on the cursor, I get list of size y, a different number. Why?

I'm calling this from a test case that has just wriiten a few hundred rows to the collection using the default WriteConcern. I understand there could be some latency with the write. What I don't understand is the different sizes of the cursor: I iterate vs toList. Aren't they basically doing the same thing (presuming I'm yielding a List from my iteration)?

val cur = findCursor(query, orderBy).skip(skip).limit(chunkSize * -1) // results size x if I iterate cur
val ret = cur.toList.map( dbo => SJ.readDB[T](dbo) ). // List size y here after toList

回答1:

The problem was found. The issue lay with the negative value passed to the limit function. I don't fully understand the semantic difference between pos/neg values to limit, or why they'd return different counts, but switching to a positive number returned the result count expected.



回答2:

They should be the same as they both iterate in the same way underneath, heres an example:

import com.mongodb.casbah.Imports._
val collection = MongoClient()("test")("myColl")
collection.drop()
1 to 1000 foreach { i => collection.insert(MongoDBObject("_id" -> i)) }

val count1 = collection.count() // Get a count from the server
val count2 = collection.find().foldLeft(0)( (x, doc) => x+1) // Iterate the cursor
val count3 = collection.find().toList.length // Use toList to iterate

assert(count1 == count2)
assert(count2 == count3)

You could get different results if new documents had been added to the database between counts or if you partially iterate the cursor then convert to list eg:

val cursor = collection.find()
cursor.next()
cursor.next()
assert(cursor.toList.length == 998)