0

I want to get an user's friends from MongoDB by using NodeJS.

In MongoDB, when I write the query, it works. The result is what I want.

However, I used the same query but I can't get same result in NodeJS. It returns an empty array. When I delete the $match part, It returns some records. I think $match part has some problem that I couldn't catch.

The queries and result are so clean, below :


MongoDB User Document Example

{
    "_id" : ObjectId("5cb14fd7db537905c89e0a72"),
    "email" : "canmustu@gmail.com",
    "username" : "canmustuu",
    "inbox" : [],
    "friends" : [ 
        {
            "user" : {
                "id" : ObjectId("5cb18680aa024b2d441f93cc")
            }
        }, 
        {
            "user" : {
                "id" : ObjectId("5cb18680aa024b2d441f93cd")
            }
        }, 
        {
            "user" : {
                "id" : ObjectId("5cb18680aa024b2d441f93ce")
            }
        }
    ],
    "friend_requests" : [],
    "created_at" : ISODate("2019-04-13T02:56:23.132Z")
}

MongoDB Query

db.getCollection('users').aggregate([
    {
        $match: { _id: ObjectId("5cb14fd7db537905c89e0a72") }
    },
    {
        $group: {
            _id: null,
            friends: { $push: "$friends.user.id" }
        }
    }
])

MongoDB Result

{
    "_id" : null,
    "friends" : [ 
        [ 
            ObjectId("5cb18680aa024b2d441f93cc"), 
            ObjectId("5cb18680aa024b2d441f93cd"), 
            ObjectId("5cb18680aa024b2d441f93ce")
        ]
    ]
}

NodeJS Query

let query = [
    {
        $match: { _id: user_id } // user_id = "5cb14fd7db537905c89e0a72"
    },
    {
        $group: {
            _id: null,
            friends: { $push: "$friends.user.id" }
        }
    }
];

User.aggregate(query, (error, result) => {

    console.log(result);

});

NodeJS Result

[]
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
canmustu
  • 2,304
  • 4
  • 21
  • 34
  • 1
    you probably need to convert `user_id` to an `ObjectId`: https://stackoverflow.com/a/32170615/1317053 – Aᴍɪʀ Apr 14 '19 at 02:14
  • Actually, I used this aggregate function in NodeJS like this before, without casting and I didn't get any problem. But now I don't know why it is not working just well. I am using "mongoose" library in NodeJS by the way. – canmustu Apr 14 '19 at 02:20
  • 2
    Using mongoose does not matter, as you still **need** to cast to the correct `ObjectId` type. An aggregation pipeline cannot use the defined schema for "autocasting" in the way that `find()` and other methods do, and simply because aggregation pipelines *alter the returned documents* so the results are *often* not related to the defined schema anyway. – Neil Lunn Apr 14 '19 at 03:30
  • 2
    FYI. Modern mongoose releases provide easy access to `ObjectId` from something like `const { Schema, { Types: { ObjectId } } } = mongoose = require("mongoose")`, which is a common statement for returning the most commonly used exports from the library. – Neil Lunn Apr 14 '19 at 03:32
  • @NeilLunn Thank you so much, for your information. It works. – canmustu Apr 14 '19 at 09:04

0 Answers0