首页 > 解决方案 > 如何在 MongoDB 中减去一个数组

问题描述

MongoDB中的数据是这样的:

{ "_id" : ObjectId("5b30d15d1e8b07d6a659ea81"), "group" : "2", "data" : { "count" : [  {  "f1" : 56,  "f2" : 48 },  {  "f1" : 95,  "f2" : 6 } ] } }
{ "_id" : ObjectId("5b30d1671e8b07d6a659ea82"), "group" : "3", "data" : { "count" : [  {  "f1" : 15,  "f2" : 72 },  {  "f1" : 56,  "f2" : 74 } ] } }
{ "_id" : ObjectId("5b30d1731e8b07d6a659ea83"), "group" : "4", "data" : { "count" : [  {  "f1" : 12,  "f2" : 96 },  {  "f1" : 85,  "f2" : 85 } ] } }
{ "_id" : ObjectId("5b30d17c1e8b07d6a659ea84"), "group" : "5", "data" : { "count" : [  {  "f1" : 73,  "f2" : 56 },  {  "f1" : 96,  "f2" : 79 } ] } }

我需要获取数据 where f1 - f2 > 0,这意味着我需要第一条和第四条记录并过滤掉第二条和第三条记录。我怎样才能做到这一点?

有没有类似的东西db.events.find({"$and":[{"difference":{"$subtract":{"data.count.f1": "data.count.f2"}}}, {"difference": {"$gt": 0}}]})

标签: mongodbmongodb-query

解决方案


使用$expr运算符(在 3.6 及更高版本中找到)作为find()方法查询表达式,您可以使用$anyElementTrue将数组作为集合并在任何元素为 true 时返回 true 否则返回 false 的运算符。空数组返回 false。

要根据上面的减法逻辑生成具有评估为真或假的元素的数组,请使用$map迭代计数数组并返回评估的逻辑。

下面显示了这一点:

db.getCollection('collection').find(
    {
        "$expr": {
            "$anyElementTrue": [
                { "$map": {
                    "input": "$data.count",
                    "as": "count",
                    "in": { 
                        "$gt": [
                            { "$subtract": [ "$$count.f1", "$$count.f2" ] },
                            0
                        ]
                    }
                } }
            ]
        }
    }
)

对于早期版本,您可以$redact按如下方式使用:

db.getCollection('collection').aggregate([
    {
        "$redact": {
            "$cond": [
                {
                    "$anyElementTrue": [
                        { "$map": {
                            "input": "$data.count",
                            "as": "count",
                            "in": { 
                                "$gt": [
                                    { "$subtract": [ "$$count.f1", "$$count.f2" ] },
                                    0
                                ]
                            }
                        } }
                    ]
                },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])

推荐阅读