je le schéma mangouste suivant:
var dataSchema = new Schema({
owner: { type: Schema.ObjectId, ref: 'User' },
time : { type: Date, default: Date.now },
eventCount:Number
});
Pour certains DataObjects le EVENTCOUNT est défini et un nombre positif, pour d'autres DataObjects le EVENTCOUNT est indéfini. Je veux concevoir un indice tel que les requêtes de ce genre sont aussi vite que possible:
db.datacollection.find({owner: <some ID>, eventCount: {$exists:true}, time: {<some time range>})
Quelle est la meilleure façon de le faire?
Voici la meilleure solution que je pouvais penser, mais je serais intéressé de savoir si quelqu'un a une meilleure solution:
Ajouter une variable booléenne isEventCount au DataSchema. Configurez le middleware mongoose de sorte que isEventCount soit calculé avant de sauvegarder l'objet sur db avec la logique suivante.
if(eventCount > 0) {
isEventCount = true;
} else {
isEventCount = false;
}
puis la construction d'un indice comme celui-ci
db.datacollection.ensureIndex({user:1, isEventCount: 1, time:1})
et ma requête en cours d'exécution comme celui-ci
db.datacollection.find({owner: <some ID>, isEventCount: true, time: {<some time range>})
Il y a des inconvénients couple à cette approche. A savoir:
- Je sauvegarde des informations redondantes dans la base de données.
- Je dois écrire du code middleware supplémentaire pour y parvenir.
- Je dois modifier les entrées existantes dans la base de données.
Quelqu'un connaît-il une meilleure solution ou une bibliothèque qui peut vous aider?
J'ai essayé ceci. Cela ne fonctionne pas.Imaginez que j'ai les données suivantes: {propriétaire: UserA, dataCount: 1, heure: hier} {propriétaire: UserA, dataCount: 1, heure: lastYear} - Imaginez qu'il y a 1000000 enregistrements comme celui-ci {propriétaire: UserA, dataCount: 2, heure: hier} L'index que vous avez décrit ci-dessus classerait les enregistrements de la manière que j'ai décrite ci-dessus. Et puis si je devais exécuter la requête: find ({propriétaire: UserA, eventCount: {$ exists: true}, heure: {depuis hier}}) le curseur devrait analyser tous les enregistrements de l'année dernière. –
"ne fonctionne pas" signifie que la requête échoue? ou vous n'aimez pas la performance? vous pouvez laisser tomber le champ de temps de l'index - comme je l'ai dit je ne connais pas la taille et la distribution de vos données, seulement vous le faites. le point est que vous n'avez pas besoin du champ calculé "isEventCount". Dans tous les cas, vous devriez comparer les différentes approches pour voir ce qui fonctionne pour vous - aucune approche de schéma/indexation ne fonctionnera pour toutes les personnes et tous les cas d'utilisation. –
Ne fonctionne pas comme je n'aime pas la performance. Je veux concevoir mes index d'une manière où pour cette requête particulière, je veux 'nscanned' pour égaler le nombre d'objets trouvés. Avec mon schéma suggéré qui est possible avec votre schéma qui n'est pas possible. (C'est le cas pour l'ensemble de données jouet suivant: '{" datacount ": 1," time ": ISODate (" 2013-06-10T15: 29: 32.603Z ")," exists ": true} {" datacount " : 2, "time": ISODate ("2014-06-10T15: 29: 32.603Z"), "exists": true} {"datacount": 1, "heure": ISODate ("2014-06-10T15: 29: 32.603Z ")," existe ": vrai}') –