I want to take the result of a Mongoose Model.aggregate
command and perform additional aggregation methods on it. The idea is that I can query the database just once, aggregate to a certain point, then perform additional aggregation methods on those results without having to requery the database again. (Code below is Coffeescript)
我想获取Mongoose Model.aggregate命令的结果并对其执行其他聚合方法。我的想法是,我可以只查询一次数据库,聚合到某个点,然后对这些结果执行其他聚合方法,而无需再次重新查询数据库。 (以下代码为Coffeescript)
firstAggregation = [
{
$geoNear: {
near:
type: "Point"
coordinates: geo
includeLocs: "geo"
distanceField: "distance"
maxDistance: distance
spherical: true
uniqueDocs: true
}
},
{
$match: { "active" : true }
}
]
secondAggregation = firstAggregation.concat [
{
$unwind: "$offers"
},
{
$group: {
_id: "$offers"
}
}
]
app.MyModel.aggregate firstAggregation, (err, results) ->
# ... do something with the first results ...
# **** apply secondAggregation here! ****
# the below doesn't work, but its what I want to achieve
results.aggregate secondAggregation, (err, secondResults) ->
# ... do something with the second results without having requeried the DB ...
Is this possible?
这可能吗?
1 个解决方案
#1
1
No, you can't pass in the results from one aggregation to a second aggregation. While you could pass a list of document _id
s to filter on using $in
, beyond that, there's really not much else you could do.
不,您无法将结果从一个聚合传递到第二个聚合。虽然您可以传递一个文档_ids列表来使用$ in进行过滤,但除此之外,您可以做的其他事情并不多。
{ $match : { _id : { $in: [ /* list of _ids */] } } }
Although given current v2.4 limitations of the aggregation framework results (capped at a 16MB result), you could perform similar logic to what you might want to have done on the database in memory on the client (in this case NodeJS).
虽然给定了聚合框架结果的当前v2.4限制(上限为16MB),但您可以执行类似于客户端(在本例中为NodeJS)的内存中数据库的逻辑。
In the example above in your question, it looks like it's just for example trying to find all of the distinct values for an array of values for the field offers
?
在您的问题上面的示例中,它看起来只是例如尝试查找字段提供的值数组的所有不同值?
offerNames = {}
for result in results
for offer in result.offers
offerNames[i] = (offerNames[i] or 0) + 1
for name, value of offerNames
console.log name + " = " + value
#1
1
No, you can't pass in the results from one aggregation to a second aggregation. While you could pass a list of document _id
s to filter on using $in
, beyond that, there's really not much else you could do.
不,您无法将结果从一个聚合传递到第二个聚合。虽然您可以传递一个文档_ids列表来使用$ in进行过滤,但除此之外,您可以做的其他事情并不多。
{ $match : { _id : { $in: [ /* list of _ids */] } } }
Although given current v2.4 limitations of the aggregation framework results (capped at a 16MB result), you could perform similar logic to what you might want to have done on the database in memory on the client (in this case NodeJS).
虽然给定了聚合框架结果的当前v2.4限制(上限为16MB),但您可以执行类似于客户端(在本例中为NodeJS)的内存中数据库的逻辑。
In the example above in your question, it looks like it's just for example trying to find all of the distinct values for an array of values for the field offers
?
在您的问题上面的示例中,它看起来只是例如尝试查找字段提供的值数组的所有不同值?
offerNames = {}
for result in results
for offer in result.offers
offerNames[i] = (offerNames[i] or 0) + 1
for name, value of offerNames
console.log name + " = " + value