Can't find documents searching by ObjectId using Mongoose - mongodb

Campaign.find {client_id:req.param('client_id')}, (error, campaigns) ->
if error
response =
error: error.message
else
for campaign in campaigns
query =
campaign_id: campaign._id
console.log query
CampaignResponse.find query, (err, campaignResponsesCount) ->
console.log campaignResponsesCount
response = campaigns
res.json response
For some reason, this returns no results. However, there are items in CampaignResponse with that specific campaign._id. I'm pretty sure this is an issue with types and casting, but I can't figure out what to do.
Any help?

A couple tips:
Try running the same query from mongodb at the command line, see if you get any results.
Is the "campaign_id" defined as an ObjectId in your schema? If so, try searching using the ObjectId type.
For example:
var ObjectId = require('mongoose').Types.ObjectId;
var query = { campaign_id: new ObjectId(campaign._id) };

Just to improve the previous (correct) answer, i use on my projects :
String.prototype.toObjectId = function() {
var ObjectId = (require('mongoose').Types.ObjectId);
return new ObjectId(this.toString());
};
// Every String can be casted in ObjectId now
console.log('545f489dea12346454ae793b'.toObjectId());

Instead of using ObjectId to find by comparing your parameters simply use
Campaign.findById {req.param('client_id'),function(err,docs)}....
when finding docs using objectId findById is the most efficient way of all...

Related

Return array of arrays as response from query in mongoose

I am working with a query in mongoose as below:
return await this.model.find({ lastname: req.lastname})
(lastname is a field in my collection)
Everything works fine, but I need a way to get the data from the query in this kind of structure:
[ [data], [data] ...., [data]]
Currently I am getting this kind of response: [ {data}, {data}....., {data}].
I have a solution for you. First of all, what you are doing is simply getting the result in default format.
In order to get the solution in your required format,
Use array, $push and $each.
**Array:** First, make sure that you create a result array
let result = [];//create an array
result = await db.find({filter}.$push({$each()});

Mongodb find() don't work

Why dosen't db.find work? The console.log gets undefined...
var course = (db.courses.find({ _id: mongo.helper.toObjectID(param.course)}));
console.log(course.body)
The way you are trying use Selects documents in a collection and returns a cursor to the selected documents., so you can't use the way you are trying to use it.
You need to use a callback() to get the records matching the query.
The below code will give result in an array format :-
db.courses.findOne({ _id: mongo.helper.toObjectID(param.course)}).toArray(function(err, result)
{
console.log(result[0]); // will give you the matched record.
})

Mongo, find through list of ids

I have a process that returns a list of String MongoDB ids,
[512d5793abb900bf3e20d012, 512d5793abb900bf3e20d011]
And I want to fire a single query to Mongo and get the matching documents back in the same order as the list.
What is the shell notation to do this?
After converting the strings into ObjectIds, you can use the $in operator to get the docs in the list. There isn't any query notation to get the docs back in the order of your list, but see here for some ways to handle that.
var ids = ['512d5793abb900bf3e20d012', '512d5793abb900bf3e20d011'];
var obj_ids = ids.map(function(id) { return ObjectId(id); });
db.test.find({_id: {$in: obj_ids}});
This works fine for me in Robo 3T. No need to create any object and just use the list of ids.
db.getCollection('my_collection').find({'_id':{$in:['aa37ba96']}})
// categoryId comma separated "5c875c27d131b755d7abed86,5c875b0ad131b755d7abed81" in request
var ids= req.body.categoryId.split(',');
db.test.find({ categoryId: { $in: ids } });
If your final purpose is to get the document with the order by your pre-get ids list, you can just convert the query result into mapping(id as key, doc as value) , and then traverse the ids list to get the doc.

Identify last document from MongoDB find() result set

I'm trying to 'stream' data from a node.js/MongoDB instance to the client using websockets. It is all working well.
But how to I identify the last document in the result? I'm using node-mongodb-native to connect to MongoDB from node.js.
A simplified example:
collection.find({}, {}, function(err, cursor) {
if (err) sys.puts(err.message);
cursor.each(function(err, doc) {
client.send(doc);
});
});
Since mongodb objectId contatins creation date you can sort by id, descending and then use limit(1):
db.collection.find().sort( { _id : -1 } ).limit(1);
Note: i am not familiar with node.js at all, above command is mongo shell command and i suppose you can easy rewrite it to node.js.
Say I have companies collection. Below snippet gives me last document in the collection.
db.companies.find({},{"_id":1}).skip(db.companies.find().count()-1);
Code cannot rely on _id as it may not be on a specific pattern always if it's a user defined value.
Use sort and limit, if you want to use cursor :
var last = null;
var findCursor = collection.find({}).cursor();
findCursor.on("data", function(data) {
last = data;
...
});
findCursor.on("end", function(data) {
// last result in last
....
});

Finding an Embedded Document by a specific property in Mongoose, Node.js, MongodDB

For this app, I'm using Node.js, MongoDB, Mongoose & Express
So I have a Param Object that contains an array of Pivots, and I want to read certain data from the pivots as outlined below
---in models.js-------------------------
var Pivot = new Schema({
value : String
, destination : String
, counter : Number
});
var Param = new Schema({
title : String
, desc : String
, pivots : [Pivot]
});
------------- in main.js --------------
var Param = db.model('Param');
app.get('/:title/:value', function(req, res){
Param.findOne({"title":req.param('title')}, function(err, record){
console.log(record.pivots);
record.pivots.find({"value":req.param('value')}, function(err, m_pivot){
pivot.counter++;
res.redirect(m_pivot.destination);
});
record.save();
});
});
I know that the code works until console.log(record.pivots), since i got a doc collection with the right pivot documents inside.
However, there does not seem to be a find method to let me match an embedded document by the 'value' property defined in the schema. Is it possible to search through this array of embedded documents using .find() or .findOne() , and if not, is there some easy way to access it through mongoose?
varunsrin,
This should do it
app.get('/:title/:value', function(req, res) {
Param.findOne({'pivots.value': req.param('value'), "title":req.param('title')}},
function(err, record) {
record.pivot.counter++;
res.redirect(m_pivot.destination);
record.save();
});
});
Note the pluralization of the query to match the field name in your schema
You can querying using embedded document properties like this:
{'pivot.value': req.param('value')}}
Update in response to comment:
app.get('/:title/:value', function(req, res) {
Param.findOne({'pivot.value': req.param('value'), "title":req.param('title')}},
function(err, record) {
record.pivot.counter++;
res.redirect(m_pivot.destination);
record.save();
});
});
I solved it temporarily using a simple for loop to parse the object array as follows:
for (var i=0; i <record.pivots.length; i++){
if (record.pivots[i].value == req.param('value')){
res.redirect(record.pivots.destination);
}
}
However, I still think that Mongoose must have a simpler way of interacting with embedded documents - and this loop is somewhat slow, especially when the number of embedded documents grows large.
If anyone has any suggestions for a faster way to search this object array either in js or with a mongoose function, please post below.
the biggest problem with this is that if your req has some fields empty (that should act as wildcard), you will not find anything since mongo tries to match empty params as well, so searching for {"user":"bob", "color":""} is not the same as {"user":"bob", "color":"red"} or {"user":"bob"}. this means that you have to first create a query object and filter out any unused parameters before you pass it in, and if you create a query object, you can no longer do something like "user.name=..." because mongo interperets this as an error since it does not first resolve the object literal into a string.
Any ideas on this problem?
ps. You'd think it would be easy enough to make an object like:
user.name="bob"; user.color:"green"; user.signup.time="12342561"
and then just use user as a query object :/
I think you are looking for the "$in" keyword?
As in:
{a: {$in: [10, "hello"]}}
source: MongoDB Queries CheatSheet