2011-01-16 5 views

Répondre

5

Vous pouvez utiliser l'opérateur $ where.

> db.orders.save({Order: {items: [1,2]}})              
> db.orders.save({Order: {items: [1,2,3]}}) 
> db.orders.find({$where:function() { if (this["Order"]["items"].length > 2) return true; }}) 
{ "_id" : ObjectId("4d334c9102bcfe450ce52585"), "Order" : { "items" : [ 1, 2, 3 ] } } 

Deux inconvénients de $ où sont qu'il ne peut pas utiliser un index et l'objet BSON doivent être convertis en un objet JavaScript, puisque vous utilisez une fonction JavaScript personnalisée sur tous les documents de la collection. Donc, $ où peut être très lent pour les grandes collections. Mais, pour les requêtes ponctuelles ou rarement exécutées, c'est extrêmement pratique. Si vous avez souvent besoin d'exécuter des requêtes comme celle-ci, vous devriez suivre la recommandation de Bugai13, puisque vous pouvez ensuite indexer la clé dans laquelle vous stockez la taille du tableau.

+3

Cela pourrait aussi écrire un peu plus court: '.Find ({$ where: "this.Order.items.length> 2"}) ' – wrdevos

7

Vous cann't requête en taille de collection embed, vous devez créer le terrain avec la taille de la collecte de ces besoins (mongo documentation db):

L'opérateur de taille $ correspond à tout tableau avec spécifié nombre d'éléments. L'exemple suivant correspondrait à l'objet {a: [ "foo"]}, puisque ce tableau a un seul élément:

db.things.find ({a: {$ size: 1}} ) ;

Vous ne pouvez pas utiliser $ size pour trouver une plage de tailles (par exemple: tableaux avec plus de 1 élément). Si vous avez besoin de requête pour une plage, créez un champ de taille supplémentaire que vous incrémentez lorsque vous ajoutez éléments.

+3

savent aussi l'inverse, par exemple: 'db.things.find ({a: {$ non: {$ size: 0}}});' –

2

J'ai aussi fait face à ce dilemme. Je ne sais pas pourquoi il n'existe pas dans MongoDB par défaut. Le moyen le plus efficace consiste à stocker également une propriété appelée count ou length ou quelque chose qui indique combien d'éléments sont dans le tableau.

Ensuite, vous pouvez indexer cette propriété et y faire des requêtes de plage. Cela gardera vos requêtes simples et rapides.

Assurez-vous simplement que votre application reste synchronisée.

+0

J'ai le même problème et cela me semble être la meilleure approche, mais ça" se sent "mal. Vous avez toujours appris que vous ne devez pas stocker de valeurs dans une base de données qui peut être calculée (elles peuvent ne pas être synchronisées). Etes-vous d'accord ou est-ce un «mode SQL» de la pensée très ? – Cimm

+0

Tout à fait d'accord, mais ce n'est que l'un des compromis de l'utilisation de MongoDB. Ce sera beaucoup mieux dans la prochaine version (2.2) qui contiendra le nouveau framework d'agrégation. Le cadre d'agrégation vous permettra de calculer les choses à la volée. Ne pas effectuer aussi bien que pré-calculer et stocker les valeurs, mais il soulage les préoccupations de désynchronisation. Un autre compromis à considérer. Vous pouvez tester ces fonctionnalités dans la branche 2.1. –

Questions connexes