Как я уже сказал в своем комментарии, избегайте хранения данных в ключах. Итак, ваша первая схема - хорошая. Рассмотрим этот набор данных:
{
"_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
}
]
}
Вы можете комбинировать оба, чтобы избежать получения документов, которые не соответствуют критериям проекции.
Надеюсь, это поможет