Can't I use an object to query in mongoose? - object

Ihave a problem when i use an object as criteria when querying in mongoose.
var id = {
cid: 111,
vid: 222,
pid: 333
};
// the following doesn't work at all
Category.find({id: id}, function(err, docs) {
//----returns nothing.
});
// while
Category.find({'id.pid': id.pid, 'id.cid': id.cid,'id.vid': id.vid}, function(err, docs) {
//----returns some docs.
});
// does work`
Is this a problem or a feature?

I don't think querying with an object in that way (nested-object format) works with mongoose, because the underlying driver (mongo-node-native) doesn't support it yet.
If you are always querying on fields id.cid, id.pid, and id.vid, you should make a compound index over all of them - creating separate indexes for each one will not help as much, because the query can only use 1 index at a time during execution.

Related

MongoDB distinct function and alphabetical sorting

I have a simple question on sorting results from the distinct command in mongodb.
I'm using Monk in my NodeJS app to get categories from my simple DB:
db.getCollection('citazioni').distinct('category')
But how can I apply a sorting function like I successfully do when I find documents with:
collection.find({}, {sort: {'_id': -1}} ??
Thank you!
Monk has support for the underlying node.js native driver distinct() method and its signature is
Collection.prototype.distinct = function (field, query, fn) { ... }
As you can see from that commit that it implements the distinct method of the node native driver collection type via the .col accessor on the selected collection object:
this.col.distinct(field, query, promise.fulfill);
Thus you can implement it together with the native JavaScript sort() method as follows :
// Perform a distinct query against the category field
db.getCollection('citazioni').distinct('category', function(err, categories) {
console.log(categories.sort());
}
Concatenate it:
db.getCollection('citazioni').distinct('category').sort({'_id': -1})
In a Node app with Mongoose:
collection.distinct('citazioni').sort({'_id': -1}).exec(function(e2, categories) {
... etc ...
}

Limit find using Monk in mongoDB

I have a large collection of documents.
I want to get the first 100 of these.
From the Monk Docs, this is the find method I am using
var documents = [];
users.find({}, function (err, docs){
for(i=0;i<100;i++)
documents.push(docs[i]);
});
This is highly wasteful since, the entire documents are anyway retrieved.
I want something like this (from the mongodb docs)
docs = db.users.find().limit( 100 );
I tried in monk,
users.find({}, function (err, docs){
for(i=0;i<docs.length;i++)
documents.push(docs[i]);
}).limit(100);
But it gives an error saying that there is no function limit in the "promise" object that is returned before it.
Is there such an option in Monk to limit the number of documents?
Yes, you can pass it as an option in the second parameter:
users.find({}, { limit : 100 }, function (err, docs){
for(i=0;i<docs.length;i++)
documents.push(docs[i]);
});
This comes from the native node mongodb driver, which monk wraps via mongoskin:
http://mongodb.github.io/node-mongodb-native/markdown-docs/queries.html#query-options
You could pass options object as a second parameter to .find():
users.find({}, {limit: 100}, next);
If you want add pagenumber and sorting, here is how to do it with monk:
users.find({}, {limit: 100, skip: pagenumber, sort: {'username': 1}})
where limit is for page size, skip is page number, sorting result by username ascending.

Using the find method on a MongoDB collection with Monk

I am working through a MEAN stack tutorial. It contains the following code as a route in index.js. The name of my Mongo collection is brandcollection.
/* GET Brand Complaints page. */
router.get('/brands', function(req, res) {
var db = req.db;
var collection = db.get('brandcollection');
collection.find({},{},function(e,docs){
res.render('brands', {
"brands" : docs
});
});
});
I would like to modify this code but I don't fully understand how the .find method is being invoked. Specifically, I have the following questions:
What objects are being passed to function(e, docs) as its arguments?
Is function(e, docs) part of the MongoDB syntax? I have looked at the docs on Mongo CRUD operations and couldn't find a reference to it. And it seems like the standard syntax for a Mongo .find operation is collection.find({},{}).someCursorLimit(). I have not seen a reference to a third parameter in the .find operation, so why is one allowed here?
If function(e, docs) is not a MongoDB operation, is it part of the Monk API?
It is clear from the tutorial that this block of code returns all of the documents in the collection and places them in an object as an attribute called "brands." However, what role specifically does function(e, docs) play in that process?
Any clarification would be much appreciated!
The first parameter is the query.
The second parameter(which is optional) is the projection i.e if you want to restrict the contents of the matched documents
collection.find( { qty: { $gt: 25 } }, { item: 1, qty: 1 },function(e,docs){})
would mean to get only the item and qty fields in the matched documents
The third parameter is the callback function which is called after the query is complete. function(e, docs) is the mongodb driver for node.js syntax. The 1st parameter e is the error. docs is the array of matched documents. If an error occurs it is given in e. If the query is successful the matched documents are given in the 2nd parameter docs(the name can be anything you want).
The cursor has various methods which can be used to manipulate the matched documents before mongoDB returns them.
collection.find( { qty: { $gt: 25 } }, { item: 1, qty: 1 })
is a cursor you can do various operations on it.
collection.find( { qty: { $gt: 25 } }, { item: 1, qty: 1 }).skip(10).limit(5).toArray(function(e,docs){
...
})
meaning you will skip the first 10 matched documents and then return a maximum of 5 documents.
All this stuff is given in the docs. I think it's better to use mongoose instead of the native driver because of the features and the popularity.

Find documents where object id $in sub array using sails.js and mongodb

So I have a model that is for a recipe where it has a relation of 'ingredients' and that is just an array of ObjectIds. When I run the following query on mongo shell it works fine and returns all my data.
Example model :
{
"name": "...",
"_id": ObjectId("530ca903746515c0161e6b9f"),
"ingredients": [
ObjectId("53069363ff7447a81a3a7a1d"),
ObjectId("53069363ff7447a81a3a7a17")
]
}
Query:
db.drink.find({"ingredients":{"$in":[ObjectId("53069364ff7447a81a3a7a87"), ObjectId("530fb948c1a3ff480d58e43c")]}});
Using sails.js though their waterline orm, they don't really have a way to query this though or at least through any possible google search that I can find. So trying to use the native driver I have something like the following -
var ings = new Array();
for (var i in req.body) {
ings.push(new ObjectID(req.body[i].toString()));
}
Drink.native(function(err, collection){
if(err){
return res.send(err, 500);
} else {
collection.find({"ingredients":{"$in":ings}}).toArray(function(err, data){
console.log(data);
});
}
});
The thing is the data array returned in the callback is always empty. If I check the 'ings' array it is an array of objectids so I am not sure why it won't return any data. If I remove the json object in the 'find' function it does return everything. Anyone have any idea how to make this query return data when using sails.js?
The code above actually is working it was an internal data issue on the mongodb where IDs were not matching between relations. When the relations were rebuilt all is working as it should be.

Can't retrieve data from the result of mongoose's find method

I want to get the data from result of mongoose's find method.
SinceIdLog.find({},['since_id','saved_date'],{sort:{'saved_date': -1}, limit:1}, function(err, docs) {
console.log(docs[0]);
// some processes
});
the output of 'console.log' in this case is what I want like following.
{ since_id: '214320642386968576',
saved_date: Sun, 17 Jun 2012 13:16:04 GMT,
_id: 4fddd8941390b38712000143 }
But, when I write like below
SinceIdLog.find({},['since_id','saved_date'],{sort:{'saved_date': -1}, limit:1}, function(err, docs) {
console.log(docs[0].since_id);
// some processes
});
the output is 'undifined'.
Do you know why?
I save the 'since_id' of Twitter API's parameter in MongoDB.
In this code, I want to get the since_id to retrieve the tweets newly updated in using OAuth.
Regards,
Remove the extraneous ] after since_id in the console.log statement.
Maybe you have getter function for since_id field which doesn't return anything? Check the schema.
I had the same problem once and I think parsing the result helped.
Try the following
SinceIdLog.find({},['since_id','saved_date'],{sort:{'saved_date': -1}, limit:1}, function(err, docs) {
docs = JSON.parse(docs);
console.log(docs[0].since_id);
// some processes
});
Thank you everyone,
I found the cause.
I haven't correctly defined the Schema like following
var Schema = mongoose.Schema,
SinceIdLog = mongoose.model('SinceIdLog', new Schema());
this works when saving the data.
var XXX = new SinceIdLog(Object);
XXX.save(function(err) {});
But it doesn't seem work well in finding.
I modified it and now it's working correctly.
var Schema = mongoose.Schema,
SinceIdLog = new Schema({
since_id: String,
saved_date: Date
}),
SinceIdSchema = mongoose.model('SinceIdLog', SinceIdLog);
Thanks!!

Resources