Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使mongodb与countDocuments()和$addFields一起工作_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

如何使mongodb与countDocuments()和$addFields一起工作

如何使mongodb与countDocuments()和$addFields一起工作,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一份结构如下的文件: { '_id': '', 'a': '', 'b': '', 'c': [ { '_id': '', 'd': '', 'f': [ { 'orderDate': 12345, 'orderProfit': 12,

我有一份结构如下的文件:

{
    '_id': '',
    'a': '',
    'b': '',
    'c': [
        {
            '_id': '',
            'd': '',
            'f': [
                {
                    'orderDate': 12345,
                    'orderProfit': 12,
                },
                {
                    'orderDate': 67891,
                    'orderProfit': 12341,
                },
                {
                    'orderDate': 23456,
                    'orderProfit': 474,
                },
            ],
        },
        {
            '_id': '',
            'd': '',
            'f': [
                {
                    'orderDate': 14232,
                    'orderProfit': 12222,
                },
                {
                    'orderDate': 643532,
                    'orderProfit': 4343,
                },
                {
                    'orderDate': 33423,
                    'orderProfit': 5555,
                },
            ],
        },
    ],
}
orderDate是一个int64,表示下订单的日期

orderProfit是表示订单利润的int64

我需要返回订单日期最大的文档,并检查orderProfit是否就是我要查找的。 为此,我在聚合查询中使用了如下查询:

[
    {
        '$addFields': {
            'orders': {
                '$map': {
                    'input': '$c',
                    'as': 'c',
                    'in': {
                        'profit': {
                            '$filter': {
                                'input': '$$c.f',
                                'cond': {
                                    '$eq': [
                                        {
                                            '$max': '$$c.f.orderDate',
                                        },
                                        '$$this.orderDate',
                                    ],
                                },
                            },
                        },
                    },
                },
            },
        },
    },
    {
        '$match': {
            '$or': [
                { 'orders.profit.orderProfit': 500 },
            ],
        },
    },
];
它工作正常

尝试将此查询添加到countDocuments查询以获取文档总数时会出现问题

使用这些文件是一项要求

我就是不能让它工作

$addFields作为未知的顶级运算符抛出。如果删除$addFields,则无法将查找最大日期的查询添加到countDocuments。如果我完全删除它,$match是一个未知的操作符

db.getCollection('orders').countDocuments(
    {
"orders.profit.orderProfit" : {"Query that was shown previously"}

})
你不能

接收查找查询时,无法将整个管道附加到该查询

然而,countDocuments只是一个包装器

返回与集合或视图的查询匹配的文档计数。该方法使用$sum表达式包装$group聚合阶段以执行计数,并可在事务中使用

基本上,此方法只执行以下聚合:

db.collection.aggregate([
    {
        $match: yourQuery
    },
    {
        $group: {
            _id: null,
            sum: {$sum: 1}
        }
    }
])
然后返回结果[0]。根据结果求和或0

因此,您可以使用自己的管道,并在最后添加此阶段,从字面上看,这将是相同的复杂性

db.collection.aggregate([
     ...
     your entire pipeline
     ...
    {
        $group: {
            _id: null,
            sum: {$sum: 1}
        }
    }
])
如果您有任何其他特定原因不想使用聚合框架,请告诉我,也许有一个解决办法。

countDocuments不允许聚合管道查询

您可以在匹配查询中使用聚合运算符,但它会导致性能问题,您可以在没有任何方法的情况下使用聚合运算符

绑定变量以在指定表达式中使用,并返回表达式的结果, vars,为$addFields操作的订单创建变量, 在,$中,映射到$$orders.profit.orderProfit嵌套数组的迭代循环,并在条件中检查$,如果找到利润金额,则它将返回true,否则返回false $anyElementTrue将检查返回的值是否为true,然后条件将为true,否则为false 第二种选择,用较少的操作员处理这种情况的另一种方法

$filter将您的两个条件与orderProfit匹配 $size可从以上$filter result中获取总结果 现在$map将返回过滤器返回的大小数组 $sum对返回结果编号求和,如果其大于0,则条件为真,否则为假
只需在末尾添加{$count:count}stage。不能这样做,确实需要它是一个countDocuments。因为它在另一个查询中使用。您不能在countDocuments方法中添加聚合管道。那么我如何处理它?如果您同时需要结果和计数,请使用$facet,{$facet:{result:[],count:[{$count:count}]}}}我很好奇,$count和$group by null之间有什么区别?$count也是一个包装器。它只执行以下两个阶段:db.collection.aggregate[{$group:{{u id:null,myCount:{$sum:1}}},{$project:{{u id:0}]工作正常,但实际上必须在countDocuments中使用,因为这是在golang中,并且必须转换为BSON,以便作为过滤器参数工作如何将其转换为BSON文档的任何线索?这是一个直接的查询,具有魅力,但试图将其添加到BSON文档中,以便由golang countDocuments筛选器参数进行处理是一个噩梦。对不起,我不懂go语言,请使用go、mongo go和mongo go驱动程序语言标签提出新问题。其他成员将获得确切的解决方案。
db.getCollection('orders').countDocuments({
  $expr: {
    $let: {
      vars: {
        orders: {
          "$map": {
            "input": "$c",
            "as": "c",
            "in": {
              "profit": {
                "$filter": {
                  "input": "$$c.f",
                  "cond": {
                    "$eq": [{ "$max": "$$c.f.orderDate" }, "$$this.orderDate"]
                  }
                }
              }
            }
          }
        }
      },
      in: {
        $anyElementTrue: {
          $map: {
            input: "$$orders.profit.orderProfit",
            in: { $in: [500, "$$this"] }
          }
        }
      }
    }
  }
})
db.getCollection('orders').countDocuments({
  $expr: {
    $sum: {
      "$map": {
        "input": "$c",
        "as": "c",
        "in": {
          $size: {
            "$filter": {
              "input": "$$c.f",
              "cond": {
                $and: [
                  { "$eq": [{ "$max": "$$c.f.orderDate" }, "$$this.orderDate"] },
                  { "$eq": ["$$this.orderProfit", 500] }
                ]
              }
            }
          }
        }
      }
    }
  }
})