在Mongo中存储每年更新的数据

时间:2018-09-04 11:19:04

标签: mongodb mongoose mongoose-schema

我有一个名为Company的集合,其中包含公司的详细信息,例如名称,地址等。但是,我还拥有该公司每年更新的财务数据。但是,我不确定如何构建此结构。我提供了两种选择,但我不确定哪一种是最好的。理想情况下,第一个选择是我所选择的选择,但是我担心,如果我想牵涉到仅提供2017年财务数据的公司,我会很努力。

有什么建议吗?

首先:动态性更高,并且不需要每年对Mongoose模式进行修改:

{
  companyName: {
    type: String
  },
  financials: [
    {
      year: {
        type: Number
      },
      revenue: {
        type: Number
      }
    }
  ]
}

第二:更易于查询:

{
  companyName: {
    type: String
  },
  financials: {
    year2017: {
      revenue: {
        type: Number
      }
    },
    year2018: {
      revenue: {
        type: Number
      }
    }
  }
}

3 个答案:

答案 0 :(得分:1)

您也可以使用此方法,将可以更轻松地查询特定财政年度的信息:

 {
    "_id" : ObjectId("5b8e7ba1325bec7b317b949f"),
    "companyName" : "ABC",
    "financials" : [ 
        {
            "2017" : {
                "revenue" : 20
            },
            "2018" : {
                "revenue" : 30
            }
        }
    ]
}

答案 1 :(得分:1)

正如我在评论中所说,避免将数据存储在密钥中。因此,您的第一个方案是一个好方案。考虑以下数据集:

{ 
    "_id" : ObjectId("5b8e7ba1325bec7b317b949f"), 
    "companyName" : "ABC", 
    "financials" : [
        {
            "year" : 2015.0, 
            "revenue" : 15.0
        }, 
        {
            "year" : 2016.0, 
            "revenue" : 18.0
        }, 
        {
            "year" : 2017.0, 
            "revenue" : 25.0
        }, 
        {
            "year" : 2018.0, 
            "revenue" : 19.0
        }
    ]
}
{ 
    "_id" : ObjectId("5b8e84234193bb17fff8d5e5"), 
    "companyName" : "BCD", 
    "financials" : [
        {
            "year" : 2016.0, 
            "revenue" : 38.0
        }, 
        {
            "year" : 2017.0, 
            "revenue" : 18.0
        }, 
        {
            "year" : 2018.0, 
            "revenue" : 5.0
        }
    ]
}
{ 
    "_id" : ObjectId("5b8e84394193bb17fff8d5e6"), 
    "companyName" : "CDE", 
    "financials" : [
        {
            "year" : 2017.0, 
            "revenue" : 3.0
        }, 
        {
            "year" : 2018.0, 
            "revenue" : 75.0
        }
    ]
}


要检索在2015年有收入的公司,请使用$elemMatch query operator

db['01'].find({financials:{$elemMatch:{year:2015}}})

结果:

{ 
    "_id" : ObjectId("5b8e7ba1325bec7b317b949f"), 
    "companyName" : "ABC", 
    "financials" : [
        {
            "year" : 2015.0, 
            "revenue" : 15.0
        }, 
        {
            "year" : 2016.0, 
            "revenue" : 18.0
        }, 
        {
            "year" : 2017.0, 
            "revenue" : 25.0
        }, 
        {
            "year" : 2018.0, 
            "revenue" : 19.0
        }
    ]
}


要仅检索每个公司的2017年,请使用$elemMatch projection operator

db['01'].find(
{}, // <= Query
{companyName:1,financials:{$elemMatch:{year:2017}}}    // <= Projection
)  

结果:

{ 
    "_id" : ObjectId("5b8e7ba1325bec7b317b949f"), 
    "companyName" : "ABC", 
    "financials" : [
        {
            "year" : 2017.0, 
            "revenue" : 25.0
        }
    ]
}
{ 
    "_id" : ObjectId("5b8e84234193bb17fff8d5e5"), 
    "companyName" : "BCD", 
    "financials" : [
        {
            "year" : 2017.0, 
            "revenue" : 18.0
        }
    ]
}
{ 
    "_id" : ObjectId("5b8e84394193bb17fff8d5e6"), 
    "companyName" : "CDE", 
    "financials" : [
        {
            "year" : 2017.0, 
            "revenue" : 3.0
        }
    ]
}

您可以将两者结合使用,以避免获取不符合投影条件的文档。

希望有帮助

答案 2 :(得分:0)

第一个版本(动态)具有仅使用固定键的巨大优势,我肯定会喜欢。

要过滤特定年份的查询,只需使用$elemMatch运算符,如here

所述

对于您的具体情况,应遵循以下原则:

db.coll.find(
   { "companyName": "stackoverflow inc."},
   { 
      "companyName": 1,
      "financials" : { $elemMatch: { "year": 2018 } }
   }
)