MongoDB, Flask, aggregate with $unwind query

与世无争的帅哥 提交于 2020-01-23 07:55:06

问题


Context

I have a Flask application connected to MongoDB using pymongo. Currently the database contains data about runs in this format:

{
    "_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"
        }
    }]
}

I am able to retrieve all the data of a specific run with this endpoint:

@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

Problem

I am working on a Flask API endpoint that will return all data from a certain run_number where the frame_number is greater than or equal to the given frame number.

So when run_number = 1 and frame_number = 2 are given as input, all data from frame numbers >= 2 from run number 1 should be retrieved.

I am new to MongoDB and have read the docs but am unable to get the data I want from the database.

What I tried

I tried to retrieve the desired data with this endpoint

@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 also tried to replace i.pop("frames.frame_number") with i.pop("_id") but both of these result in "The specified data starting from frame number: 2 was not found".

What should I change in order to retrieve the desired data from my MongoDB?

EDIT Expected output

"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:


You can achieve that by using an $unwind and then a $group with $push, like this:

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"
      }
    }
  }
])

the $unwind will destruct your array and then you filter the results and after $group them again

Or you can do it as well using $filter

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


来源:https://stackoverflow.com/questions/59323316/mongodb-flask-aggregate-with-unwind-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!