如何在MongoDB中查询嵌套文档?

时间:2018-10-06 08:18:37

标签: mongodb

我对数据库和MongoDB非常陌生。我试图将财务报表信息存储在数据库中,每个文档都代表一家公司。

我已经创建了一个嵌套文档(可能不是一个好方法),如下图所示。最高级包括年度报表,基本信息,关键图和临时报表。在年度报表中,有不同的日期。在日期范围内,我们有不同类型的语句(INC,BAL,CAS),然后内部级别包含实际数据。 enter image description here

我的问题是如何查询数据库,以使所有包含2017语句的文档(例如)?

现在,年份格式为YYYY-MM_DD。但我只想过滤YYYY。

2 个答案:

答案 0 :(得分:1)

我强烈不建议使用变量(此处为date,INC)作为字段名称。这将(更多)难以查询,更新,您将无法使用索引。因此,即使在少数静态值(INC,BAL,CAS)的情况下它是“可接受的”(但不正确的做法),在大多数情况下这也是一个非常糟糕的主意。

我的建议是将架构更改为易于使用的内容,例如:

[
  {
    "annual_statement": [
        { "date": ISODate("2017-12-31"),
          "INC":{
              "SREV": 1322.5,
              "RTLR": 1423.4,
              ...
            },
          "BAL":{...},
          "CAS":{...}
        },
      {   "date": ISODate("2017-12-31"),
          "INC":{
              "SREV": 1322.5,
              "RTLR": 1423.4,
              ...
            },
          "BAL":{...},
          "CAS":{...}
        }
    ]
  }
]

要查询此架构,请使用以下命令:

db.collection.find({
  "annual_statement": {
    $elemMatch: {
      date: {
        $lt: ISODate("2018-01-01"),
        $gte: ISODate("2017-01-01"),

      }
    }
  }
})

将退还至少截止日期为2017年的整个文档。

添加如下所示的预测将只返回匹配的年度报表:

db.collection.find({
  "annual_statement": {
    $elemMatch: {
      date: {
        $lt: ISODate("2018-01-01"),
        $gte: ISODate("2017-01-01"),

      }
    }
  }
},
{
  "annual_statement": {
    $elemMatch: {
      date: {
        $lt: ISODate("2018-01-01"),
        $gte: ISODate("2017-01-01"),

      }
    }
  }
})

答案 1 :(得分:0)

使用$ exists(请注意,我使用的是python-下面的pymongo驱动程序语法-您可能有所不同) https://docs.mongodb.com/manual/reference/operator/query/exists/

示例:按公司查找所有“ 2017”“ INC”记录。

year_exists=db.collection.find({'Annual.2017-12-31': {'$exists':True}})

for business in year_exists:
     bus_name = business['BasicInfo']['CompanyName']
     financials_INC = business['Annual']['2017-12-31']['INC'])
     print(bus_name, financials_INC)