I have a collection like this:
[
{ parent: 'a', d1: '1', d2: '2', d3: '3', w: 10 },
{ parent: 'a', d1: '1', d2: '2', d3: '3', w: 20 },
{ parent: 'a', d1: '1', d2: '2', d3: '3', w: 30 },
{ parent: 'a', d1: '1', d2: '2', d3: '3', w: 40 },
{ parent: 'a', d1: '1', d2: '2', d3: '3', w: 50 },
{ parent: 'a', d1: '1', d2: '2', d3: '3', w: 60 },
{ parent: 'b', d1: '1', d2: '2', d3: '3', w: 10 },
{ parent: 'b', d1: '1', d2: '2', d3: '3', w: 13 },
{ parent: 'b', d1: '1', d2: '2', d3: '3', w: 14 },
{ parent: 'b', d1: '1', d2: '2', d3: '3', w: 15 },
{ parent: 'c', d1: '1', d2: '2', d3: '3', w: 10 },
{ parent: 'c', d1: '1', d2: '2', d3: '3', w: 100 },
{ parent: 'c', d1: '1', d2: '2', d3: '3', w: 200 },
{ parent: 'c', d1: '1', d2: '2', d3: '3', w: 300 }
]
Given a query with relevant parent ids, ['b','c']
, I need to get back the first 3 results for each parent, hopefully DESC-sorted by w
:
[
{ parent: 'b', d1: '1', d2: '2', d3: '3', w: 15 },
{ parent: 'b', d1: '1', d2: '2', d3: '3', w: 14 },
{ parent: 'b', d1: '1', d2: '2', d3: '3', w: 13 },
{ parent: 'c', d1: '1', d2: '2', d3: '3', w: 300 },
{ parent: 'c', d1: '1', d2: '2', d3: '3', w: 200 },
{ parent: 'c', d1: '1', d2: '2', d3: '3', w: 100 }
]
Using .find()
and .limit()
would return the first N results overall, not the first N for each parent
. Using .aggregate()
I figured out how to aggregate by parent
but I couldn't figure out how to $limit
by parent, nor how to return the entire documents as {parent: 'b', items: [{..}, {..}] }
instead of just the group data. I can get either parent
, which I already had, or maybe parent
and an array on some field using $push
, but that's still no good.
Lastly I also tried .mapReduce
but that seems like overkill, wouldn't I have to emit(this.project, this);
for the aggregation part? how would I even $limit on that? by hand? It's quite underdocumented.
Anyways, some direction on which way to go would be great here. I'm using mongoose@latest
.