Хранение данных, которые ежегодно обновляются в Монго - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть коллекция с именем 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 голосов
/ 04 сентября 2018

Первая версия (динамическая) имеет большое преимущество использования только фиксированных ключей, что я бы определенно предпочел.

В запросе для фильтрации по конкретным годам нужно использовать только оператор $elemMatch, как описано здесь

В вашем конкретном случае это должно выглядеть следующим образом:

db.coll.find(
   { "companyName": "stackoverflow inc."},
   { 
      "companyName": 1,
      "financials" : { $elemMatch: { "year": 2018 } }
   }
)
0 голосов
/ 04 сентября 2018

Как я уже сказал в своем комментарии, избегайте хранения данных в ключах. Итак, ваша первая схема - хорошая. Рассмотрим этот набор данных:

{ 
    "_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 запрос оператор :

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 оператор :

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
        }
    ]
}

Вы можете комбинировать оба, чтобы избежать получения документов, которые не соответствуют критериям проекции.

Надеюсь, это поможет

0 голосов
/ 04 сентября 2018

Вы также можете воспользоваться этим, вам будет проще запрашивать данные за определенный финансовый год:

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