mongo 查询缺少键的对象

use*_*276 4 mongodb mongodb-query

我有一个 Mongo 数据库,其数据以这种格式存储:

{ "_id" : ObjectId("53e27f602041f3c6fe5373a8"), 
  "miles" : 112650, 
  "history" : [ { "date" : ISODate("2014-05-26T00:00:00Z"), "price" : 8995 }, 
                { "date" : ISODate("2014-06-01T00:00:00Z"), "price" : 8995 } ] }
Run Code Online (Sandbox Code Playgroud)

数据库中的对象可以在历史数组中存储任意数量的“日期”和“价格”数据点。但是,数据库中的某些对象将具有多个历史数据点,但最后一个“日期”键/值对不匹配带有“价格”键/值对,如下所示:

{ "_id" : ObjectId("53e27f602041f3c6fe5373a8"), 
  "miles" : 112650, 
  "history" : [ { "date" : ISODate("2014-05-26T00:00:00Z"), "price" : 8995 }, 
                { "date" : ISODate("2014-06-01T00:00:00Z")} ] }
Run Code Online (Sandbox Code Playgroud)

我需要查询数据库以查找 1) 历史数组中的每个条目都有日期和价格的所有对象,2) 历史数组中具有与“价格”条目不匹配的“日期”条目的所有对象。感谢您的帮助!

Nei*_*unn 5

首先回答“2”,原因会变得很清楚,您基本上要求的是找到其数组元素包含“日期”值但不包含“价格”的文档。因为你想要的数组元素匹配有两个条件$elemMatch。并测试您想要的字段是否存在,$exists如下所示:

db.collection.find({
  "history": {
    "$elemMatch": {
      "date": { "$exists": true },
      "price": { "$exists": false }
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

这会返回您的第二个样本,因为数组条目之一没有“价格”。

为了回答“1”,这基本上只是与上面的逻辑相反$not,所以这里引入的只是运算符:

db.collection.find({
  "history": {
    "$not": { 
      "$elemMatch": {
        "date": { "$exists": true },
        "price": { "$exists": false }
      }
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

这会生成样本中的第一个文档,因为在这种情况下,“价格”存在于所有元素中,因此断言条件将是,false但这可以通过使用来扭转$not