RejectedSoftware Forums

Sign up

find() in MongoDB

I am trying to query a MongoDB database from Vibe and am having trouble figuring out how to specify non-trivial queries.

I have a collection called images, which contains a set of documents describing images, and includes among its fields a
title field and, of course, the _id field.

I would like to execute a query that returns just the titles from each document. From the Mongo client this query looks
as follows:

db.images.find( { }, { title: 1 } )

and it returns records that look like:

{ "_id" : ObjectId("522b08dde8d4a38eb60cc4eb"), "title" : "Dog" }
{ "_id" : ObjectId("522f44f555d703955051bd6d"), "title" : "Cat" }
{ "_id" : ObjectId("522f450b55d703955051bd6e"), "title" : "House" }

In my vibe project I have the following code that I hope will replicate the above query:

Now would I make the same query from the Vibe MongoDB client (currently this code just prints the results to
the log):

foreach( img; images.find( Bson.EmptyObject, ["title"]  ) ) {
    logInfo("Image: %s", img.toJson() );
}

This prints only the _id field, not the title field as I had hoped.

Image: {"_id":"522b08dde8d4a38eb60cc4eb"}
Image: {"_id":"522f44f555d703955051bd6d"}
Image: {"_id":"522f450b55d703955051bd6e"}

I've tried numerous variants on this, including (I will skip all the combinations I tried before finding a reference to Bson.EmptyObject in an older post on this forum :o) :

Bson.EmptyObject, ["{title: 1}"] 
Bson.EmptyObject, ["title:", "1"]
Bson.EmptyObject, ["title"]

Also, how would I specify something along the lines of, if I just want
images with 'Dog' in the title.

db.images.find( { title: /Dog/ }, { title: 1 } )

I tried poking through the source on GitHub to figure this out, but I guess my D-coding isn't quite up to snuff yet.
Cheers,
Craig

Re: find() in MongoDB

On Tue, 17 Sep 2013 17:14:14 GMT, Craig Dillabaugh wrote:

db.images.find( { }, { title: 1 } )

An associative array is required on the D side instead of the JS object:

images.find(Bson.EmptyObject, ["title": 1]);
db.images.find( { title: /Dog/ }, { title: 1 } )

I've never used a regular expression, so this may not work. But I would expect this to be equivalent:

images.find(["title": BsonRegex("/Dog/", "")], ["title": 1]);
// or maybe:
images.find(["title": BsonRegex("Dog", "")], ["title": 1]);

Running mongod with verbose logging turned on can give a hint (or, ultimately, using WireShark). I'll look into that if none of those doesn't work.

Re: find() in MongoDB

On Tue, 17 Sep 2013 19:00:20 GMT, Sönke Ludwig wrote:

On Tue, 17 Sep 2013 17:14:14 GMT, Craig Dillabaugh wrote:

db.images.find( { }, { title: 1 } )

An associative array is required on the D side instead of the JS object:

images.find(Bson.EmptyObject, ["title": 1]);
db.images.find( { title: /Dog/ }, { title: 1 } )

I've never used a regular expression, so this may not work. But I would expect this to be equivalent:

images.find(["title": BsonRegex("/Dog/", "")], ["title": 1]);
// or maybe:
images.find(["title": BsonRegex("Dog", "")], ["title": 1]);

Running mongod with verbose logging turned on can give a hint (or, ultimately, using WireShark). I'll look into that if none of those doesn't work.

Thanks, I will try a few of these suggestions out and report back!

Craig

Re: find() in MongoDB

On Tue, 17 Sep 2013 19:00:20 GMT, Sönke Ludwig wrote:

On Tue, 17 Sep 2013 17:14:14 GMT, Craig Dillabaugh wrote:

db.images.find( { }, { title: 1 } )

An associative array is required on the D side instead of the JS object:

images.find(Bson.EmptyObject, ["title": 1]);
db.images.find( { title: /Dog/ }, { title: 1 } )

I've never used a regular expression, so this may not work. But I would expect this to be equivalent:

images.find(["title": BsonRegex("/Dog/", "")], ["title": 1]);
// or maybe:
images.find(["title": BsonRegex("Dog", "")], ["title": 1]);

Running mongod with verbose logging turned on can give a hint (or, ultimately, using WireShark). I'll look into that if none of those doesn't work.

For finding specific documents, using the second option:

images.find(["title": BsonRegex("Dog", "")], ["title": 1]);

Does the trick.

Re: find() in MongoDB

Am 17.09.2013 21:41, schrieb Craig Dillabaugh:

On Tue, 17 Sep 2013 19:00:20 GMT, Sönke Ludwig wrote:

On Tue, 17 Sep 2013 17:14:14 GMT, Craig Dillabaugh wrote:

db.images.find( { }, { title: 1 } )

An associative array is required on the D side instead of the JS object:

images.find(Bson.EmptyObject, ["title": 1]);
db.images.find( { title: /Dog/ }, { title: 1 } )

I've never used a regular expression, so this may not work. But I would expect this to be equivalent:

images.find(["title": BsonRegex("/Dog/", "")], ["title": 1]);
// or maybe:
images.find(["title": BsonRegex("Dog", "")], ["title": 1]);

Running mongod with verbose logging turned on can give a hint (or, ultimately, using WireShark). I'll look into that if none of those doesn't work.

For finding specific documents, using the second option:

images.find(["title": BsonRegex("Dog", "")], ["title": 1]);

Does the trick.

Good to know. I'm leaving myself a note to add this as an example.

Re: find() in MongoDB

Also worth noting that while vibe.d does not provide some convenience functions Mongo shell does, MongoDB protocol is designed in such way that almost any possible query can be reduced to find(). One can always sniff the request from shell by wireshark and reconstruct it manually in D code, see https://github.com/rejectedsoftware/vibe.d/issues/295 for example.

(You may already know this but it is a common newbie issue)

Re: find() in MongoDB

On Wed, 18 Sep 2013 12:19:33 GMT, Dicebot wrote:

Also worth noting that while vibe.d does not provide some convenience functions Mongo shell does, MongoDB protocol is designed in such way that almost any possible query can be reduced to find(). One can always sniff the request from shell by wireshark and reconstruct it manually in D code, see https://github.com/rejectedsoftware/vibe.d/issues/295 for example.

(You may already know this but it is a common newbie issue)

If it is a newbie issue, you can be assured I will run into it! Thanks for the tip.