Reputation: 17332
I'm using the official MongoDB driver for Node.js.
And this is how my message data is structured. As you can see, every post has a timestamp, an userId and the id of the topic.
[
{
"_id" : ObjectId("5b0abb48b20c1b4b92365145"),
"topicId" : "XN7iqmCFD4jpgJZ6f",
"timestamp" : 1527429960,
"user" : "5b0869636f4e363e300d105a",
"content" : "lorem ipsum"
}
]
Now I need to check if there are topics, which newest post (=highest timestamp) doesn't match my own ID. With that I do know which topic has a new answer (which is not my own post).
So I started with this:
db.messages.find({
$query: {
user: { $ne: "myUserId" }
},
$orderby: {
timestamp: -1
}
}).limit(1).toArray()
My problem is, that I do not know how to group my query by the topicId. And somehow there seems to be wrong syntax in my attempt.
Upvotes: 2
Views: 42
Reputation: 46441
You have to use aggregate to group by topicId
and then $sort
for sorting according to time and then $limit
to limit the query
db.messages.aggregate([
{ $match: { user: { $ne: "myUserId" } }},
{ $group: {
_id: "$topicId",
timestamp: { $first: "$timestamp"},
user: { $first: "$user" },
content: { $first: "$content" }
}},
{ $sort: { timestamp: -1 } },
{ $limit: 1 }
])
Upvotes: 1
Reputation: 32
Use aggregate pipeline to do this instead of find.
1) $match $ne :"myUserId"
2) $sort timestamp:-1
3) $group topicId $first
A sample query I have written in the past..
{ "$match": { $and: [ {'latestTimeStamp': { "$gte": new Date('3/11/2018') }}, {'latestTimeStamp': { "$lte": new Date('4/12/2018') }} ]} },
{ $unwind: '$latestSev'},
{ $sort: {'latestSev.sevRating': -1}},
{ $group:{ _id:{_id:'$_id', latestTimeStamp:'$latestTimeStamp', latestLikeli:'$latestLikeli', latestControl:'$latestControl', residualRatingArray:'$residualRatingArray'},
latestMaxImpName: {$first:'$latestSev.impName'} ,
latestMaxSevRating: {$first:'$latestSev.sevRating'}
}
}
Upvotes: 0