Учитывая коллекцию MongoDB в следующей структуре
{
"_id" : 1,
"system_id" : "123",
"sub_systems" : [
{
"sub_system_id" : "456",
"status" : "connected",
"messages_relayed" : [ ] // An array of message_ids that have been relayed
}
]}
Я хотел бы создать запрос, чтобы вернуть, сколько сообщений было передано каждым подсистема. Я начал с этого:
db.messages.aggregate([{
"$project": {
"_id": 0,
"num_of_msgs_relayed": {
"$cond":
{"if": { "$isArray": "$sub_systems.messages_relayed" },
"then": { "$size": "$sub_systems.messages_relayed" },
"else": 0}
}}}]);
К моему удивлению, результат:
{ "num_of_msgs_relayed" : 1 }
ВОПРОС: я ожидал, что запрос вернет значение 0, так как в основном я проецирую $размер пустого массива! Какова причина этого 1?
P.S.: The following command can be used to create the data shown on messages collection:
db.runCommand( { insert: "messages", documents: [{'_id': 1, 'system_id': '123', 'sub_systems':[{'status': 'connected', 'messages_relayed': []}]}] } )



Вы можете попробовать простейший запрос ниже, чтобы посмотреть, как MongoDB интерпретирует sub_systems.messages_relayed:
db.messages.aggregate([
{ "$project": { "arr": "$sub_systems.messages_relayed"}}
]);
Таким образом, этот запрос вернет массив массивов, поскольку sub_systems — это один внешний массив, а messages_relayed — другой. Вот почему вы получаете 1 вместо 0.
Чтобы «проецировать размер пустого массива», вы должны использовать $расслабиться до того, как ваш проект и ниже агрегация вернет 0 вместо 1.
db.messages.aggregate([
{ $unwind: "$sub_systems" },
{
$project: {
_id: 0,
num_of_msgs_relayed: {
$cond: {
if: { $isArray: "$sub_systems.messages_relayed" },
then: { $size: "$sub_systems.messages_relayed" },
else: 0
}
}
}
}
])
$unwind, затем$groupс$sum. docs.mongodb.com/manual/reference/operator/aggregation/sum/…