Using the c# driver for MongoDB I can easily construct a query against which I can then add SetSkip() and SetLimit() parameters to constrict the result set to a certain size.
However I'd like to be able to know what item count of the query would be before applying Skip and Take without executing the query and loading the entire result set (which could be huge) into memory.
It looks like I can do this with MongoDB directly through the shell by using the count() command. e.g.:
db.item.find( { "FieldToMatch" : "ValueToMatch" } ).count()
Which just returns an integer and that's exactly what I want. But I can't see a way in the documentation of doing this through the C# driver. Is it possible?
(It should be noted that we're already using the query builder extensively, so ideally I'd much rather do this through the query builder than start issuing commands down to the shell through the driver, if that's possible. But if that's the only solution then an example would be helpful, thanks.)
Cheers,
Matt
You can do it like this:
var server = MongoServer.Create("mongodb://localhost:27020");
var database = server.GetDatabase("someDb");
var collection = database.GetCollection<Type>("item");
var cursor = collection.Find(Query.EQ("FieldToMatch" : "ValueToMatch"));
var count = cursor.Count();
Some notes:
You should have only one instance of server (singleton)
latest driver version actually returns long count instead of int
Cursor only fetches data once you iterate
You can configure a lot of things like skip, take, specify fields to return in cursor before actually load data (start iteration)
Count() method of cursor loads only document count
I'm using the Driver 2.3.0 and now is also possible to do that like this:
...
IMongoCollection<entity> Collection = db.GetCollection<entity>(CollectionName);
var yourFilter = Builders<entity>.Filter.Where(o => o.prop == value);
long countResut = Collection.Count(yourFilter);
Related
I am trying to work with mongo shell and I am having challenges in storing the value inside of mongo shell
when I find a user in the document users, i store it in the variable doc
> var doc = db.users.find({"username":"anil"});
When I type doc in the mongo shell i see the json object
> doc
{ "_id" : ObjectId("57325aaa48d9231b11e5cb81"), "username" : "anil", "email" : "mongodb#gmail.com" }
However when I type doc again, i dont see anything. its gone.. what am I doing wrong here ?
> doc
>
It might be something simple but I am not getting it. Can someone point out what I am doing wrong ?
This because find returns a cursor and you can only consume all the value once. Here because you filter your document based on _id value, in the return cursor you only have one document which is consumed the first time you time. If you need to iterate your result many times, you will need to return an array that contains all the documents from the cursor using toArray, but in your case what you need is findOne
when you open a mongo shell it tries to find a mongod server and connects to test by default. when you assign some variable in mongo shell to some document in mongod, it actually fetches the document from the database, to get the same result again you need to connect to the database again (means you need to type var doc = db.users.find({"username":"anil"}); again). Unlike the scenario where you define var doc = 4 in shell and typing doc will return 4 every time.
If you want to stop transmission at the beginning and do some processing then you need to add null after it like
var doc = db.users.find({"username":"anil"});null;
// do your work on doc
an ex.
One other option could be to use the next() function of the find() cursor. This will give the value of the first record in to the variable and it will persist. Then any required operation can be done on the variable.
I would need to filter a plain JS object using a MongoDB request (Meteor server side) this ideally without inserting it into a DB, is this possible ?
Something like Mongo.match(myPlainObject, {"fieldName":"valueExpected"});
Why would you do this within Mongo? You can test JSON objects using the built-in Check functionality in Meteor. A big advantage is that this test can be made available on both client and server, which you often want to do for efficiency/security.
You can use Check for date ranges or anything else as well. Whatever is not covered by the predefined matches, can be done like this:
NonEmptyString = Match.Where(function (x) {
check(x, String);
return x.length > 0;
});
check(arg, NonEmptyString);
You could write any date related matches you need. (Keeping in mind that you can also make sure it is in fact a Date by stating:
check(arg,Date);
Is it possible to store the result of a mongodb statement in array using jquery
I have like this
Polls_Coll.find({},{question:1});
I want all the question filed records to store in array some thing like
var arr[]=Polls_Coll.find({},{question:1});
I know above thing is wrong. I need something like that.
I need it for autocompletion. Now i'm taking source from one collection like this
source:_(Product_Mobiles.find().fetch()).pluck("title")
I want data from multiple sources and store it in array
Thanks
Using the mongo console you can do this with .toArray() like
var results = db.collection.find({}).toArray();
However, this might depend on the driver you are using... I guess the javascript driver has it as well.
If your problem is putting all the results from multiple sources into a single array:
How to merge two arrays in Javascript and de-duplicate items
You could merge the two arrays if thats what you mean:
var results = collection.find({}).fetch();
var results2 = collection2.find({}).fetch();
results = results.concat(results2);
Then you can do pluck
_(results).pluck("title");
Also you can't use db. in Meteor you have to use the name of the collection varaible you defined with new Meteor.Collection
I have a db set up in mongo that I'm accessing with pymongo.
I'd like to be able to pull a small set of fields into a list of dictionaries. So, something like what I get in the mongo shell when I type...
db.find({},{"variable1_of_interest":1, "variable2_of_interest":1}).limit(2).pretty()
I'd like a python statement like:
x = db.find({},{"variable1_of_interest":1, "variable2_of_interest":1})
where x is an array structure of some kind rather than a cursor---that is, instead of iterating, like:
data = []
x = db.find({},{"variable1_of_interest":1, "variable2_of_interest":1})
for i in x:
data.append(x)
Is it possible that I could use MapReduce to bring this into a one-liner? Something like
db.find({},{"variable1_of_interest":1, "variable2_of_interest":1}).map_reduce(mapper, reducer, "data")
I intend to output this dataset to R for some analysis, but I'd like concentrate the IO in Python.
You don't need to call mapReduce, you just turn the cursor into a list like so:
>>> data = list(col.find({},{"a":1,"b":1,"_id":0}).limit(2))
>>> data
[{u'a': 1.0, u'b': 2.0}, {u'a': 2.0, u'b': 3.0}]
where col is your db.collection object.
But caution with large/huge result cause every thing is loaded into memory.
What you can do is to call mapReduce in pymongo and pass it the find query as an argument, it could be like this:
db.yourcollection.Map_reduce(map_function, reduce_function,query='{}')
About the projections I think that you would need to do them in the reduce function since query only specify the selection criteria as it says in the mongo documentation
Building off of Asya's answer:
If you wanted a list of just one value in each entry as opposed to a list of objects--using a list comprehension worked for me.
I.e. if each object represents a user and the database stored their email, and you say wanted all the users that were 15 years old
user_emails = [user['email'] for user in db.people.find( {'age' : 15} )]
More here
I am trying to use mongodb's ObjectID to do a range query on the insertion time of a given collection. I can't really find any documentation that this is possible, except for this blog entry: http://mongotips.com/b/a-few-objectid-tricks/ .
I want to fetch all documents created after a given timestamp. Using the nodejs driver, this is what I have:
var timeId = ObjectId.createFromTime(timestamp);
var query = {
localUser: userId,
_id: {$gte: timeId}
};
var cursor = collection.find(query).sort({_id: 1});
I always get the same amount of records (19 in a collection of 27), independent of the timestamp. I noticed that createFromTime only fills the bytes in the objectid related to time, the other ones are left at 0 (like this: 4f6198be0000000000000000).
The reason that I try to use an ObjectID for this, is that I need the timestamp when inserting the document on the mongodb server, not when passing the document to the mongodb driver in node.
Anyone knows how to make this work, or has another idea how to generate and query insertion times that were generated on the mongodb server?
Not sure about nodejs driver in ruby, you can simply apply range queries like this.
jan_id = BSON::ObjectId.from_time(Time.utc(2012, 1, 1))
feb_id = BSON::ObjectId.from_time(Time.utc(2012, 2, 1))
#users.find({'_id' => {'$gte' => jan_id, '$lt' => feb_id}})
make sure
var timeId = ObjectId.createFromTime(timestamp) is creating an ObjectId.
Also try query without localuser