1

I am trying to make a populate query with mongodb (using mongoose as orm), and it doesn´t work 100%. I mean that I get all the entries from the document where I apply the populate... ALL, the entries that (on the crossed document) match with the match query (and I obtain a nested object), but I get the others too (and the nested object is null).

This is what I have done:
MODELS

var userSchema = Schema({
    name: String,
    email: String,
    idiom: String
});
var ticketsSchema = Shema({
    user_id:{ type:Schema.Types.ObjectId, ref:'User', required: true},
    date: Date,
    points: Number,
    kart: String
});

POPULATE

tickets.find()
    .populate(
    {
        path: 'user_id',
        match:{name:"user1"}
    }
    ).exec(function (err, result) {
        if (err) return handleError(err);
        res.send(result);
    });

And a possible result could be:

Object[0]  
__v: 0
_id: "5655b68ccbe953bc2a78da54"
date: "2015-11-25T13:24:28.561Z"
date: "2015-11-25T13:24:28.561Z"  
points: 50  
kart: "Senior"  
user_id: Object  
    __v: 0
    _company: 0  
    _id: "5655b656cbe953bc2a78da53"  
    name: "user1"  
    email: "user1@mail.com"  
    idiom: "es"

Object[1]  
__v: 0
_id: "5655b732e0685c441fddb99b"
date: "2015-11-25T13:27:14.608Z" 
points: 75  
kart: "Pro Senior"  
user_id: Object
    __v: 0
    _company: 0  
    _id: "5655b656cbe953bc2a78da53" 
    name: "user1"  
    email: "user1@mail.com"  
    idiom: "es"

Object[2]  
__v: 0
_id: "56564613701da2981aa017d6"
date: "2015-11-25T23:36:51.774Z"
points: 75  
kart: "Pro Senior"  
user_id: null

Object[3]  
__v: 0
_id: "565646ee701da2981aa017d8"
date: "2015-11-25T23:40:30.308Z"
points: 75  
kart: "Pro Senior"  
user_id: null

This isn´t exactly what I want to do... I would want that the two last doesn´t show up.

EDIT

I think I didn´t explain clear myself clearly... what I want to do is a JOIN query...
I have seen that I need use a mapreduce, I tried to do but I don´t found a place where it is explained for... dummies. All what I could do until now is this:

ticketsDB.find()
    .populate(
    {
        path: 'user_id',
        match:req.body
    }
    ).exec(function (err, result) {
        if (err) return res.send(err);
        reslt=[];
        for(var i in result)
            if(result[i].user_id)reslt.push(result[i]);
        console.log(reslt);
        res.send(reslt);
    });

Thank you.

Eloy Fernández Franco
  • 1,350
  • 1
  • 24
  • 47
  • 1
    http://stackoverflow.com/questions/32165302/trying-to-populate-in-mongoose-only-if-ref-is-not-null-not-working – ma08 Nov 29 '15 at 11:52
  • 1
    See also: http://stackoverflow.com/questions/19380738/mongoose-nested-query-on-model-by-field-of-its-referenced-model – JohnnyHK Nov 30 '15 at 03:41
  • @ma08 thanks for your comment... I think that I didn´t explain good at all, my problem wasn´t that user_id could be null on some entries of the ticket collection (user_id is a require field). What I am trying to do is a JOIN query between users and tickets. – Eloy Fernández Franco Nov 30 '15 at 08:31
  • Hi @JohnnyHK, there is something missing for my case... the problem with this answer is that I don´t get the data from the users, I mean, the user_id field is only the id, and not an object with all the info of each user. – Eloy Fernández Franco Nov 30 '15 at 08:39
  • 1
    You can still call `populate('user_id')` on your `ticketsDB` query in your deleted answer to do that: `ticketsDB.find({user_id: {$in: ids}}).populate('user_id').exec(...);`. – JohnnyHK Nov 30 '15 at 14:01
  • Thanks @JohnnyHK it works :) if you post as an answer I´ll mark as the correct. – Eloy Fernández Franco Nov 30 '15 at 14:32
  • Great. Just edit your deleted answer to include the final solution and then undelete it and accept it. It was very close already. – JohnnyHK Nov 30 '15 at 14:37
  • Hi again @JohnnyHK I would want to ask you if you see a better answer my edditing or if you see any deficiency. Thank you. – Eloy Fernández Franco Dec 09 '15 at 09:05

1 Answers1

0

Thanks @JohnnyHK by his comment, I found the solution here: Mongoose nested query on Model by field of its referenced model

And now the code is something like:

usersDB.find(req.body, function(err, docs) {
    var ids = docs.map(function(doc) { return doc._id; });
    ticketsDB.find({user_id: {$in: ids}})
    .populate('user_id').exec(function (err, result) {
        if (err) return res.send(err);
        reslt=[];
        for(var i in result)
            if(result[i].user_id)reslt.push(result[i]);
        res.send(reslt);
    });
});

Where req.body is {name:"user 1"} or {email:"user1@user.com"}.

EDIT

I was thinking a little (sorry, it will happen no more ;p ), and I think that there is a way to remove the mapping of this query. Now my answer is this:

usersDB.find(req.body).distinct("_id", function(err, docs) {
    ticketsDB.find({user_id: {$in: docs}})
    .populate('user_id').exec(function (err, result) {
        if (err) return res.send(err);
        reslt=[];
        for(var i in result)
            if(result[i].user_id)reslt.push(result[i]);
        res.send(reslt);
    });
});

Could be that valid??

Community
  • 1
  • 1
Eloy Fernández Franco
  • 1,350
  • 1
  • 24
  • 47