MongoDb 3.6 Cursor Count and Data ... Warning NOOB and SQL Developer

49 views
Skip to first unread message

Mike Craig

unread,
Jan 13, 2018, 8:30:16 PM1/13/18
to mongodb-user
SLOWLY making the conversion over to MongoDB from a lifetime of SQL Server so please...bear with me.

Very commonly, I need to run a query to find out if any documents are found then if there are, iterate through all the found documents and do something with them...for now, just think display one or two fields of data from each document found.

var testcollection = db.getCollection(testcollectionname)

...
var c1= testcollection.aggregate([{$group: {_id: { $concat: [ "$LastName", ", ", "$FirstName", " ", {$ifNull:["$MiddleName",""]}] } ,  count : { $sum: 1}}},{$match: {count : { $gt : 1 }}}, {$project: {_id:1 , "duplicates":"$count"}}])
print(c1.itcount())


That returns "1", which is correct...this is a duplicate checking routine and there are in fact TWO identical "name" combinations per the group concat of last, first and middle.  So, so far, perfect.

Now, I want to iterate through that cursor and for each document, just print the _id value to the console so I can see which name is duplicated.  As with other DB environments, Cursors are typically forward only so I presume once itcount() executes on the cursor, everything has been iterated and the cursor is at end of line.  So, at first, keeping it simple, I do THIS next...

c1.forEach(printjson)


but I get no output at all.  If the cursor is exhausted of iterable data, I get that.  Of course, cuz eyes so smart...let's just do the query again for a total of the following...

var c1= testcollection.aggregate([{$group: {_id: { $concat: [ "$LastName", ", ", "$FirstName", " ", {$ifNull:["$MiddleName",""]}] } ,  count : { $sum: 1}}},{$match: {count : { $gt : 1 }}}, {$project: {_id:1 , "duplicates":"$count"}}])
print(c1.itcount())
c1
= testcollection.aggregate([{$group: {_id: { $concat: [ "$LastName", ", ", "$FirstName", " ", {$ifNull:["$MiddleName",""]}] } ,  count : { $sum: 1}}},{$match: {count : { $gt : 1 }}}, {$project: {_id:1 , "duplicates":"$count"}}])
c1
.forEach(printjson)

and everything just locks up...keeps gyrating so long, I just abort the process.  I tried "rescoping" by adding "var" in front of the second thinking that was needed and it did not make any difference.  And two other really strange things that come out of these tests include:

NOTHING I do for the second pass, including making it a WHOLE NEW VARIABLE, gets that second output stream to come out, so...

var c1= testcollection.aggregate([{$group: {_id: { $concat: [ "$LastName", ", ", "$FirstName", " ", {$ifNull:["$MiddleName",""]}] } ,  count : { $sum: 1}}},{$match: {count : { $gt : 1 }}}, {$project: {_id:1 , "duplicates":"$count"}}])
c1
.itcount()
var c2= testcollection.aggregate([{$group: {_id: { $concat: [ "$LastName", ", ", "$FirstName", " ", {$ifNull:["$MiddleName",""]}] } ,  count : { $sum: 1}}},{$match: {count : { $gt : 1 }}}, {$project: {_id:1 , "duplicates":"$count"}}])
c2
.forEach(printjson)

The other weird thing is that while itcount()  works for the c1 cursor results from the aggregate, count() throws

var c1= testcollection.aggregate([{$group: {_id: { $concat: [ "$LastName", ", ", "$FirstName", " ", {$ifNull:["$MiddleName",""]}] } ,  count : { $sum: 1}}},{$match: {count : { $gt : 1 }}}, {$project: {_id:1 , "duplicates":"$count"}}])
c1
.count()


2018-01-13T20:22:08.149-0500 E QUERY    [thread1] TypeError: c1.count is not a function :

but if c1 IS a cursor...why would count() throw an error.

It seems likely I'm just doing something wrong or missing a nuance of cursors...but having been so settled for so long in the straight SQL world, I'm flummoxed.  More importantly...this is a pretty "common" type of routine for developers consuming SQL, write/execute the query, get back a result set, check to see if the result has any records/data, if it does, process that result set...so I'm also wondering if there is simply a smarter way to do this.  This, by the way, is all Javascript processing and in these testing scenarios, I'm using the latest version of MongoDB and Studio 3T.

Thanks for any insight or direction to other resources that might provide some guidance.

Mike

Kevin Adistambha

unread,
Jan 21, 2018, 10:43:33 PM1/21/18
to mongodb-user

Hi Mike

but I get no output at all. If the cursor is exhausted of iterable data, I get that.

Actually, the itcount() method iterates and exhausts the cursor (see cursor.itcount()). This is why when you subsequently called c1.forEach(), nothing is printed as the cursor was exhausted.

but if c1 IS a cursor…why would count() throw an error.

This is because c1 was an aggregation cursor, which contains a different set of methods vs. a find() cursor. The list of methods available for an aggregation cursor can be found in Cursor Behavior.

I hope this clears it up. If you require more help, please post some example documents and what operation you need to do.

Best regards
Kevin

Reply all
Reply to author
Forward
0 new messages