node.js - Get result as an array instead of documents in mongodb for an attribute -
i have user collection schema
{ name: string, books: [ id: { type: schema.types.objectid, ref: 'book' } , name: string ] }
is possible array of book ids instead of object?
something like:
["53eb797a63ff0e8229b4aca1", "53eb797a63ff0e8229b4aca2", "53eb797a63ff0e8229b4aca3"]
or
{ids: ["53eb797a63ff0e8229b4aca1", "53eb797a63ff0e8229b4aca2", "53eb797a63ff0e8229b4aca3"]}
and not
{ _id: objectid("53eb79d863ff0e8229b97448"), books:[ {"id" : objectid("53eb797a63ff0e8229b4aca1") }, { "id" : objectid("53eb797a63ff0e8229b4acac") }, { "id" : objectid("53eb797a63ff0e8229b4acad") } ] }
currently doing
user.findone({}, {"books.id":1} ,function(err, result){ var bookids = []; result.books.foreach(function(book){ bookids.push(book.id); }); });
is there better way?
it done aggregation pipeline, using $unwind , $group.
db.users.aggregate({ $unwind: '$books' }, { $group: { _id: 'books', ids: { $addtoset: '$books.id' } } })
the same operation using mongoose model.aggregate()
method:
user.aggregate().unwind('$books').group( _id: 'books', ids: { $addtoset: '$books.id' } }).exec(function(err, res) { // use res[0].ids })
note books
here not mongoose document, plain js object.
you can add $match select part of users collection run aggregation query on.
for example, may select 1 particular user:
user.aggregate().match({ _id: uid }).unwind('$books').group( _id: 'books', ids: { $addtoset: '$books.id' } }).exec(function(err, res) { // use res[0].ids })
but if you're not interested in aggregating books different users single array, it's best without using $group
, $unwind
:
user.aggregate().match({ _id: uid }).project({ _id: 0, ids: '$books.id' }).exec(function(err, users) { // use users[0].ids })
Comments
Post a Comment