MongoDB,Flask与$ unwind查询聚合

时间:2019-12-13 13:12:46

标签: python mongodb flask pymongo

上下文

我有一个使用pymongo连接到MongoDB的Flask应用程序。当前,数据库包含有关以这种格式运行的数据:

{
    "_id": {
        "$oid": "5df031cec687bf2b4c4349b9"
    },
    "run_number": "1",
    "frames": [{
        "frame_number": 1,
        "data": {
            "brake": "0.1",
            "steer": "0.4",
            "throttle": "0.6"
        }
    }, {
        "frame_number": 2,
        "data": {
            "brake": "0.2",
            "steer": "0.8",
            "throttle": "0.6"
        }
    }, {
        "frame_number": 3,
        "data": {
            "brake": "0.6",
            "steer": "0.2",
            "throttle": "0.1"
        }
    }]
}

我能够使用此端点检索特定运行的所有数据:

@app.route('/pitcrew-purple/api/v1/<run_number>/')
def get_run(run_number):
    if run_number:
        data = []
        for i in mongodb.pitcrewdb.find({"run_number": run_number}):
            i.pop('_id')
            data.append(i)
        if not data:
            return "No data was found for run number {}".format(run_number), 400
        return jsonify(data), 200
    return "No run_number was given", 400

问题

我正在开发一个Flask API端点,它将从某个特定的run_number返回所有数据,其中frame_number大于或等于给定的帧号。

因此,当输入run_number = 1frame_number = 2作为输入时,应检索运行编号1的帧编号> = 2的所有数据。

我是MongoDB的新手,已经阅读了文档,但无法从数据库中获取所需的数据。

我尝试过的

我尝试通过此端点检索所需的数据

@app.route('/pitcrew-purple/api/v1/<run_number>/<start_frame_number>/')
def get_rundata_from_start_frame(run_number, start_frame_number):
    if run_number and start_frame_number:
        data = []
        query = mongodb.pitcrewdb.find(
            {"run_number": run_number, "frames.frame_number": {"$gte": start_frame_number}}
        )
        for i in query:
            i.pop("frames.frame_number")
            data.append(i)
        if not data:
            return "The specified data starting from frame number: {} was not found".format(start_frame_number), 400
        return jsonify(data), 200
    return "No parameters were given", 400

我还尝试将i.pop("frames.frame_number")替换为i.pop("_id"),但两者都导致“指定的数据从帧号开始:2未找到”。

为了从MongoDB中检索所需的数据,我应该改变什么?

EDIT预期输出

"run_number": "1",
    "frames": [{  
      {
        "frame_number": 2,
        "data": {
            "brake": "0.2",
            "steer": "0.8",
            "throttle": "0.6"
        }
    }, {
        "frame_number": 3,
        "data": {
            "brake": "0.6",
            "steer": "0.2",
            "throttle": "0.1"
        }
    }]

1 个答案:

答案 0 :(得分:1)

您可以使用$unwind,然后再将$group$push一起使用,例如:

db.pitcrewdb.aggregate([
  {
    "$match": {
      "run_number": "1",
      "frames.frame_number": {
        "$gte": 2
      }
    }
  },
  {
    "$project": {
      "_id": 0
    }
  },
  {
    "$unwind": "$frames"
  },
  {
    "$match": {
      "frames.frame_number": {
        "$gte": 2
      }
    }
  },
  {
    "$group": {
      "_id": "$run_number",
      "frames": {
        "$push": "$frames"
      }
    }
  }
])

$unwind将破坏数组,然后过滤结果,并在$group之后再次

或者您也可以使用$filter

db.pitcrewdb.aggregate([
  {
    "$match": {
      "run_number": "1"
    }
  },
  {
    "$project": {
      "_id": 0,
      "frames": {
        $filter: {
          input: "$frames",
          as: "frame",
          cond: {
            $gte: [
              "$$frame.frame_number",
              2
            ]
          }
        }
      }
    }
  }
])