首页 文章

在Mongoose / MongoDB中的文档中过滤数组,子文档,数组中的数组

提问于
浏览
2

使用Mongoose(甚至只是MongoDB查询),我想返回一个匹配所有文档的查询结果:

a)“units”字段(子文档数组)包含一个带有“unit”字段的子文档,该字段本身包含一个带有“_id”字段的子文档,该字段与给定的字符串值匹配,

b)“units”字段包含一个带有“period”字段(Date对象数组)的子文档,其中给定日期位于数组中第一个和第二个元素之间 .

数据结构如下所示:

{
  "_id" : ObjectId("5984bdfdb3ac279e39f156d4"),
  "surname" : "Dare",
  "firstname" : "Dan",
  "units" : [{
               "period" : [
                            ISODate("2018-01-01T00:00:00.000Z"), 
                            ISODate("2019-12-31T00:00:00.000Z")
                          ],
               "unit" : {
                          "unit_name" : "My test unit",
                           "_id" : "5979437c6d346eb7d074497a"
                        }
            }]
}

我已经尝试过使用.find()和.aggregate()的各种组合,例如使用$ project和$ filter on the period数组,在unit._id上的$ elemMatch之后,但无济于事 - 我得到的错误如“不能在数组上使用$ filter” .

任何正确方向的指针都会受到赞赏 - 至少在最合适的查询类型和最有效的方法来组合运算符以生成我之后的数据集时 .

架构(根据要求):

{
    surname: {
    type: String
  },
    firstname: {
    type: String
  },
  units: {
    type: [{
      unit: {
        _id: String,
        unit_name: String,
      },
      period: [Date]
    }]
  }
}

1 回答

  • 1

    我想我的问题太复杂了 . 不确定这是否是最有效的方法,但使用$和运算符似乎提供了我正在寻找的东西:

    db.getCollection("records").find({ "$and": [
    {"units.unit._id": "5979437c6d346eb7d074497a"},
    {"units.unit_period.0": {"$gte": new Date('2018-12-31T00:00:00.000Z')} },
    {"units.unit_period.1": {"$lte": new Date('2020-12-31T00:00:00.000Z')} } ]
    })
    

    更新

    根据Neil Lunn在评论中的建议,使用$ elemMatch而不是$并且肯定似乎是更好的选择,原因如下 .

    因此,这是我将要采用的解决方案;即使用#emMmMatch来匹配那些包含嵌入式子文档和数组的元素,其中可以通过键上的简单点符号访问和匹配值 .

    我想尝试使用$ filter和$ aggregate过度编码解决方案,当检索我需要的数据集实际上就像这样简单:

    db.getCollection("records").find({ "units": 
      { "$elemMatch": 
        { "unit._id": "5979437c6d346eb7d074497a", 
          "unit_period.0": { "$gte": new Date('2019-12-31") },
          "unit_period.1": { "$lte": new Date("2020-12-31") }
        } 
      })
    

相关问题