mongoDB:$ project按值查找数组索引(如何在$ project-statment中使用filter()?)

时间:2014-07-26 12:02:50

标签: mongodb aggregation-framework

我有一个包含这样数据的集合:

 {
    _id: 9999,
    sales : [
          {date: "mo", sum: 2},
          {date: "we", sum: 5},
    ]
 },
 {
    _id: 2323,
    sales : [
          {date: "mo", sum: 10},
          {date: "we", sum: 23},
    ]
 }

我需要在集合中的每个文档的sales-array中使用" sum" -field(但仅针对一个给定的日期字符串)。我试试这个:

db.foo.aggregate(
{ $project : {
  sales_day: "$sales.filter(function(item) { return item.date = "we" });",
 }
})

如果添加任何过滤器函数,我们总是设置一个空数组。即使它过滤器函数一直返回true。

我需要像mongodb中的Array.prototype.filter-Function这样的东西。

如果我有这个:

var tofind = "do";
sales = sales.filter(function(item) {
   return item.date = tofind;
});

sales_day = sales.sum;

我在日期字段中搜索的字符串必须是动态的,因为它可以随每个查询而变化。我也不能使用某些组语法,因为有一个非常复杂的查询 - 这只是部分,但这部分我不能开始工作。

在进一步的聚合步骤中,我需要管道中的这些数据(对于date =" mo"作为示例)

{
    _id: 9999,
    sales_day: 2
 },
 {
    _id: 2323,
    sales_day: 5
 }

有人有想法吗?

注意:之后我会在管道中做更多的步骤 - 但我需要现场" sales_day"进一步分组/排序。

1 个答案:

答案 0 :(得分:3)

您无法在管道中调用JavaScript函数,而是使用aggregate而不是$match执行任何$project过滤。

var toFind = 'we';
db.foo.aggregate([
    // Filter to just the docs that contain at least one of the sales elements
    {$match: {'sales.date': toFind}},
    // Duplicate each doc, once per sales element.
    {$unwind: '$sales'},
    // Filter to just the docs with the sales element we need
    {$match: {'sales.date': toFind}},
    // Reshape the docs to have a sales_day field
    {$project: {sales_day: '$sales.sum'}}
])

输出:

{
    "result" : [ 
        {
            "_id" : 9999,
            "sales_day" : 5
        }, 
        {
            "_id" : 2323,
            "sales_day" : 23
        }
    ],
    "ok" : 1
}