具有自身数据的MongoDB条件查询

时间:2019-07-23 05:47:52

标签: mongodb mongodb-query aggregation-framework

假设集合中有4个用户。

> db.users.find().pretty()
{
    "_id" : ObjectId("5d369b451b48d91cba76c618"),
    "user_id" : 1,
    "final_score" : 65,
    "max_score" : 15,
    "min_score" : 15,
}
{
    "_id" : ObjectId("5d369b451b48d91cba76c619"),
    "user_id" : 2,
    "final_score" : 70,
    "max_score" : 15,
    "min_score" : 15,
}
{
    "_id" : ObjectId("5d369b451b48d91cba76c61a"),
    "user_id" : 3,
    "final_score" : 60,
    "max_score" : 15,
    "min_score" : 15,
}
{
    "_id" : ObjectId("5d369b451b48d91cba76c61b"),
    "user_id" : 4,
    "final_score" : 83,
    "max_score" : 15,
    "min_score" : 15,
}

我要提取满足以下条件的用户。

  • final_score> = user_id=3的{​​{1}} + final_score
  • each document's max_score <= final_score的{​​{1}}-user_id=3

用MySQL表示,非常简单。

final_score

但是我不知道该如何使用mongodb进行查询?

谢谢。

编辑

我认为可以用each document's min_score执行。

所以我这样查询。

SELECT * FROM users
WHERE final_score <= 60 + users.max_score AND final_score >= 60 - users.min_score

但是它什么也没返回

2 个答案:

答案 0 :(得分:0)

这里的困难来自以下事实:您需要运行两个单独的管道(一个管道用于获取用户3的值,第二个管道用于过滤所有文档)。在Aggregation Framework中,您可以使用$facet运算符来执行此操作,该运算符允许您运行多个管道,然后在后续步骤中继续处理数据。要比较数据,可以使用$filter并获得原始形状,您需要使用$unwind$replaceRoot

将嵌套数组转换为单独的文档
db.users.aggregate([
    {
        $facet: {
            user3: [
                { $match: { user_id: 3 } }
            ],
            docs: [
                { $match: {} }
            ]
        }
    },
    {
        $addFields: {
            user3: { $arrayElemAt: [ "$user3", 0 ] }
        }
    },
    {
        $project: {
            docs: {
                $filter: {
                    input: "$docs",
                    cond: {
                        $and: [
                            { $lte: [ "$$this.final_score", { $add: [ "$user3.final_score", "$$this.max_score" ] } ] },
                            { $gte: [ "$$this.final_score", { $subtract: [ "$user3.final_score", "$$this.max_score" ] } ] },
                        ]
                    }
                }
            }
        }
    },
    {
        $unwind: "$docs"
    },
    {
        $replaceRoot: {
            newRoot: "$docs"
        }
    }
])

Mongo Playground

答案 1 :(得分:0)

根据您的描述,我想您已经知道user3的得分是60

在这种情况下:

db.collection.aggregate([
  {
    $addFields: {
      match: {
        $and: [
          {
            $gte: [
              "$final_score",
              {
                $subtract: [
                  60,
                  "$min_score"
                ]
              }
            ]
          },
          {
            $lte: [
              "$final_score",
              {
                $add: [
                  60,
                  "$max_score"
                ]
              }
            ]
          }
        ]
      }
    }
  },
  {
    $match: {
      match: true
    }
  },
  {
    $project: {
      match: 0
    }
  }
])

mongoplayground