/ / MongoDB Project / Aggregate pour obtenir tous les derniers sous-documents des entrées de tableaux - mongodb, mongodb-query, framework d'agrégation

Projet MongoDB / Aggregate pour obtenir toutes les dernières entrées de tableaux dans les sous-documents - mongodb, mongodb-query, aggregation-framework

J'utilise MongoDB pour stocker des données de séries chronologiques avec des lacunes. Chaque document appartient à un élément et contient les modifications pour plusieurs points de mesure. Chaque point de mesure a un identifiant, j'ai utilisé le schéma d'identification suivant some-id-XXX dans l'exemple ci-dessous.

L'application écrit uniquement les modifications apportées à lasous-document spécifique. Par conséquent, il existe la possibilité de lacunes dans la série, l'APP charge tout le document, vérifie les modifications et met à jour le ou les sous-documents ("some-id-1" par exemple) qui a des changements.

{
"_id": "XXX-DAY_OF_YEAR",
"date": null /* A date used for the TTL index */,
"series" : {
"some-id-1" : [
{
"ts" : 1457959837,
"value" : 385,
"meta" : "some meta info …"
},
{
"ts" : 1457959837,
"value" : 385,
"meta" : "some meta info …"
},
{
"ts" : 1458286255,
"value" : 380,
"meta" : "some meta info …"
},
{
"ts" : 1458346606,
"value" : 375,
"meta" : "some meta info …"
},
{
"ts" : 1458381111,
"value" : 368,
"meta" : "some meta info …"
},
{
"ts" : 1458381461,
"value" : 365,
"meta" : "some meta info …"
},
{
"ts" : 1458606338,
"value" : 385,
"meta" : "some meta info …"
},
{
"ts" : 1458606338,
"expired": true
}
],
"some-id-2" : [
{
"ts" : 1439802083,
"value" : 430,
"meta" : "some meta info …"
}
],
"some-id-42" : [
{
"ts" : 1457545167,
"value" : 518,
"meta" : "some meta info …"
},
{
"ts" : 1458483441,
"value" : 1034,
"meta" : "some meta info …"
},
{
"ts" : 1458518979,
"value" : 518,
"meta" : "some meta info …"
}
],
"some-id-1337" : [
{
"ts" : 1458017854,
"value" : 361,
"meta" : "some meta info …"
},
{
"ts" : 1458050773,
"value" : 384,
"meta" : "some meta info …"
},
{
"ts" : 1458115173,
"value" : 383,
"meta" : "some meta info …"
},
{
"ts" : 1458143968,
"value" : 382,
"meta" : "some meta info …"
},
{
"ts" : 1458176011,
"value" : 381,
"meta" : "some meta info …"
},
{
"ts" : 1458212600,
"value" : 384,
"meta" : "some meta info …"
},
{
"ts" : 1458245285,
"value" : 383,
"meta" : "some meta info …"
},
{
"ts" : 1458277108,
"value" : 382,
"meta" : "some meta info …"
},
{
"ts" : 1458309875,
"value" : 379,
"meta" : "some meta info …"
},
{
"ts" : 1458338258,
"value" : 378,
"meta" : "some meta info …"
},
{
"ts" : 1458374471,
"value" : 374,
"meta" : "some meta info …"
},
{
"ts" : 1458405856,
"value" : 364,
"meta" : "some meta info …"
},
{
"ts" : 1458435330,
"value" : 363,
"meta" : "some meta info …"
},
{
"ts" : 1458471185,
"value" : 362,
"meta" : "some meta info …"
},
{
"ts" : 1458500103,
"value" : 361,
"meta" : "some meta info …"
},
{
"ts" : 1458535837,
"value" : 360,
"meta" : "some meta info …"
},
{
"ts" : 1458568805,
"value" : 364,
"meta" : "some meta info …"
},
{
"ts" : 1458633188,
"value" : 384,
"meta" : "some meta info …"
}
]
}
}

Le problème avec cette approche est le trafic généré par le chargement de tout le document, qui est nécessaire pour vérifier les modifications ou les lacunes.

Si je pouvais récupérer uniquement la valeur la plus récente (la dernière valeur du tableau), le trafic serait réduit.

{
"series" : {
"some-id-1" : [
{
"ts" : 1458606338,
"expired": true
}
],
"some-id-2" : [
{
"ts" : 1439802083,
"value" : 430,
"meta" : "some meta info …"
}
],
"some-id-42" : [
{
"ts" : 1458518979,
"value" : 518,
"meta" : "some meta info …"
}
],
"some-id-1337" : [
{
"ts" : 1458633188,
"value" : 384,
"meta" : "some meta info …"
}
]
}
}

Tant que je connais l'ID, je peux utiliser une projection pour récupérer la dernière entrée récente.

db.Series.find(
{ "series.some-id-42" : { $exists: true } },
{ "series.some-id-42.$": -1}
)

Mais comme un changement peut contenir des lacunes, je ne connais pas tous les identifiants se produisant dans le document de la série cible.

Y a-t-il une possibilité d'archiver cela en utilisant le cadre d'agrégation ou avec une projection intelligente?

Ma seule idée est de stocker les valeurs récentes sous une forme et un projet plus compacts uniquement {last_recent: 1}:

{
"recent": {
"some-id-1" : 0,
"some-id-2" : 430,
"some-id-42" : 518,
"some-id-1337" : 384
}
"series" : { /* … */ }
}

Mais j'espère qu'il existe une solution plus élégante à ce problème.

Réponses:

0 pour la réponse № 1

Le problème principal est que vous "stockez des données dans les noms de champ, c'est-à-dire l'ID.

Le schéma devrait probablement être:

{
"series": [
{
"id": 1,
"content": [
{
"ts": 1458606338,
"expired": true
}
]
},
{
"id": 2,
"content": [
{
"ts": 1439802083,
"value": 430,
"meta": "some meta info …"
}
]
},
{
"id": 42,
"content": [
{
"ts": 1458518979,
"value": 518,
"meta": "some meta info …"
}
]
},
{
"id": 1337,
"content": [
{
"ts": 1458633188,
"value": 384,
"meta": "some meta info …"
}
]
}
]
}