Reputation: 79
I need to take only unique values from collection. For example:
const userID = `user1`;
const users = await Chat
.find({'$or': [{to: userID}, {from: userID}]})
.select(`-_id to from`)
.lean();
// users will be like:
[
{from: `user1`, to: `user2`},
{from: `user1`, to: `user2`},
{from: `user1`, to: `user2`},
{from: `user2`, to: `user1`},
{from: `user3`, to: `user1`},
// ... 10089 more items
];
// and I want this in result
const result = [`user2`, `user3`]; // exclude current user too
I know that I can do this using JS. I can create an array from users and run new Set()
, but it will be slow. Can Mongoose do this instead of me?
Upvotes: 4
Views: 661
Reputation: 36144
You can try aggregation query,
$match
your condition$group
by null and construct unique array of from
user and to
user$setUnion
to get unique users
from from
and to
array$filter
to iterate loop of above union array and remove current userconst userID = mongoose.Types.ObjectId(`user1`);
const users = await Chat.aggregate([
{ $match: { $or: [{ to: userID }, { from: userID }] } },
{
$group: {
_id: null,
from: { $addToSet: "$from" },
to: { $addToSet: "$to" }
}
},
{
$project: {
_id: 0,
users: {
$filter: {
input: { $setUnion: ["$from", "$to"] },
cond: { $ne: ["$$this", userID] }
}
}
}
}
]).exec();
console.log(users[0].users);
Upvotes: 3