简体   繁体   中英

How to query by a field in an array of sub-documents with greater than condition?

data: [
    {
            "_id" : ObjectId("5ebda923a52984db48ab45f6"),
            "detectorid" : 1371,
            "loopdata" : [
                    {
                            "starttime" : "9/15/2011 0:00:00",
                            "volume" : 2,
                            "speed" : 65,
                            "occupancy" : 2,
                            "status" : 2,
                            "dqflags" : 0
                    },
                    {
                            "starttime" : "9/15/2011 0:00:20",
                            "volume" : 2,
                            "speed" : 53,
                            "occupancy" : 2,
                            "status" : 2,
                            "dqflags" : 0
                    },
                    {
                            "starttime" : "9/15/2011 0:00:40",
                            "volume" : 0,
                            "speed" : "",
                            "occupancy" : 0,
                            "status" : 0,
                            "dqflags" : 0
                    }
]

Hey guys, this is the data that I have in my collection. I want to return back the speed is over 53. I have tried and db.collection.find({"data.speed":{$gt:53}})

it returned the wrong results (basically returned everything) and I have no idea what I wrong. Any hints guys? Thanks

I made to you two solutions:

  1. If you just want to keep a speeds field and the _id document, this solve the problem:

Query:

db.collection.aggregate([
  // $filter will apply the condition to every element of the array
  // in this case the array is [65, 53 ""]
  {
    $project: {
      "speeds": {
        $filter: {
          "input": "$loopdata.speed",
          "as": "speed",
          "cond": {
            $and: [
              {
                $eq: [
                  {
                    $type: "$$speed" // check if the type is numeric
                  },
                  "double"
                ]
              },
              {
                $gt: [
                  "$$speed",  // check if it's greater than 53
                  53
                ]
              }
            ]
          }
        }
      }
    }
  }
])

Result:

[
  {
    "_id": ObjectId("5ebda923a52984db48ab45f6"),
    "speeds": [
      65
    ]
  }
]
  1. Now if you want to keep all the fields, and filter just the array loopdata , so this solves the problem:

Query 2:

db.collection.aggregate([
  {
    $addFields: {
      "loopdata": {
        $filter: {
          "input": "$loopdata",
          "as": "data",
          "cond": {
            $and: [
              {
                $eq: [
                  {
                    $type: "$$data.speed"
                  },
                  "double"
                ]
              },
              {
                $gt: [
                  "$$data.speed",
                  53
                ]
              }
            ]
          }
        }
      }
    }
  }
])

Result:

[
  {
    "_id": ObjectId("5ebda923a52984db48ab45f6"),
    "detectorid": 1371,
    "loopdata": [
      {
        "dqflags": 0,
        "occupancy": 2,
        "speed": 65,
        "starttime": "9/15/2011 0:00:00",
        "status": 2,
        "volume": 2
      }
    ]
  }
]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM