Considérons un document MongoDB dans la collection des users
:
{ username : 'Alex', tags: ['C#', 'Java', 'C++'] }
Est-il possible d’obtenir la longueur du tableau de tags
du côté serveur (sans passer les balises au client)?
Je vous remercie!
Maintenant, MongoDB (version 2.6) prend en charge les opérations de $size
en agrégation.
De la documentation:
{ : { $size: } }
Ce que vous voulez peut être accompli comme suit avec soit:
db.users.aggregate( [ { $group: { _id: "$username", tags_count: {$first: {$size: "$tags" }} } } ] )
ou
db.users.aggregate( [ { $project: { tags_count: {$size: "$tags"} } } ] )
Si le nom d’utilisateur Alex est unique, vous pouvez utiliser le code suivant:
db.test.insert({username:"Alex", tags: ['C#', 'Java', 'C++'] }); db.test.aggregate( {$match: {username : "Alex"}}, {$unwind: "$tags"}, {$project: {count:{$add:1}}}, {$group: {_id: null, number: {$sum: "$count" }}} ); { "result" : [ { "_id" : null, "number" : 3 } ], "ok" : 1 }
Je pense qu’il serait plus efficace de calculer le nombre d’étiquettes sur chaque enregistrement (sous la forme d’un champ distinct) en utilisant $ inc peut-être ou via un travail sur une planification.
Vous pouvez aussi faire cela avec map / Reduce (l’ exemple canonique ), mais cela ne semble pas être ce que vous voudriez.
Je ne suis pas sûr qu’il soit possible de faire exactement ce que vous demandez, mais vous pouvez interroger tous les documents qui correspondent à une certaine taille avec la taille $ …
> db.collection.find({ tags : { $size: 3 }});
Cela vous donnerait tous les documents avec 3 tags …
La réponse de xmm.dev peut être simplifiée: au lieu d’avoir un «champ» intermédiaire, vous pouvez additionner directement dans le groupe $:
db.test.aggregate( {$match: {username : "Alex"}}, {$unwind: "$tags"}, {$group: {_id: null, number: {$sum: 1 }}} )
Actuellement, la seule façon de le faire semble utiliser db.eval
, mais cela verrouille la firebase database pour d’autres opérations .
Le moyen le plus rapide serait d’append un champ supplémentaire qui stocke la longueur du tableau et de le maintenir par les opérations $ inc et $ push .
J’ai fait un petit travail autour de moi car j’avais besoin d’interroger la taille du tableau et de retourner s’il était supérieur à 0 mais pouvait être n’importe quoi de 1-3.
Voici ma solution:
db.test.find($or : [{$field : { $exists : true, $size : 1}}, {$field : { $exists : true, $size : 2}}, {$field : { $exists : true, $size : 3}}, ])
Cela renvoie essentiellement un document lorsque l’atsortingbut existe et la taille est 1, 2 ou 3. L’utilisateur peut append plus d’instructions et incrémenter si elles recherchent une taille spécifique ou dans une plage. Je sais que ce n’est pas parfait mais cela a fonctionné et a été relativement rapide. Je n’avais que 1 à 3 tailles dans mon atsortingbut, donc cette solution a fonctionné.