2011-10-11 5 views
4

(Désolé si c'est une question triviale.)Comment faire une requête dans cette structure de document imbriquée (MongoDB)?

J'ai des documents qui ressemble à ceci (syntaxe Python):

{ 
    '_id': SomeObjectId, 
    'features': [ 
       {'id': 'featureX' , 'value': 6}, 
       {'id': 'featureY', 'value': 45} 
       ] 
} 

Avec cette structure, il est facile de trouver tous les documents contenant « featureX » dans le liste des fonctionnalités. Mais je suis également intéressé par la récupération de la valeur associée dans le sous-document. Je pense en Python si je reçois le document avec une requête comme celle-ci: db.articles.find({'features.id': 'featureX'}) alors je devrais itérer sur le tableau 'features' pour trouver la bonne 'valeur'.

Y at-il un autre type de requête qui peut me donner la valeur intéressante (dans ce cas je n'ai pas besoin de récupérer le document complet, seulement la partie avec {'id': 'featureX', 'value': 6}, qui ne sera pas à une valeur d'indice prévisible dans le tableau

PS:. Je pense que je vais concevoir différemment le document, mais je suis toujours intéressé de savoir si le Resquest ci-dessus est possible

.

Voici la nouvelle structure:

{ 
'_id': SomeObjectId, 
'features': { 
       'featureX': { 'someproperty':'aaa', 'value':6 }, 
       'featureY': {'someproperty' :'bbb', 'value':45} 
      } 
} 

y at-il question à ce sujet d Esgin? Dans mon cas 'featureX', 'featureY' est unique, donc les utiliser comme touches de dictionnaire n'est pas un problème.

Modifier: Je dois préciser que je vais devoir mettre à jour atomiquement dire 'featureX' et 'featureY' dans un document et MongoDB does not support transactions. La seconde conception, bien qu'elle ne permette pas d'extraire un sous-document, devrait faciliter l'obtention rapide des informations souhaitées dans le code client, en supposant que je puisse interroger les sous-documents ayant une certaine clé.

Je pense que cette requête devrait faire le travail:

result = db.articles.find_one({ 'features.featureX': {'$exists': True} }) 
interesting_value = result['features']['featureX']['value'] 

Répondre

2

J'ai répondu ce couple de fois à ramasser les sous-documents seulement de la collection mongo here et here

Simplement il y a aucun moyen de le faire actuellement. C'est le comportement du filtrage du document intégré à plusieurs niveaux, normalement le filtre correspondant retournerait le document entier, pas les sous-ensembles.

Il existe deux problèmes en suspens dans mongo liés à ce positional ($) operator in fields to return specifier et Ability to make use of a subdocument's data whose contents were used to satisfy a query using the $ operator. (Veuillez vous connecter pour voter si vous aviez vraiment besoin de la fonctionnalité)

Et votre autre schéma n'est pas utile ici.

donc vous devez stocker les chaque élément dans le document séparé comme celui-ci pour le faire fonctionner la façon dont vous vouliez

fonction 1

{ 
'_id': SomeObjectId, 
'name' :'some name', 
'value': 'feature 1', 
'some_field' : 'zzz' 
} 

fonction 2

{ 
'_id': SomeObjectId, 
'name' :'some name', 
'value': 'feature 2', 
'some_field' : 'zzz' 
} 

et l'interrogation

db.features.find({'_id':someobjectid}) 

ne retournera que la caractéristique spécifique

+0

Merci. Je pense que mon schéma alternatif donne la possibilité de récupérer rapidement la valeur désirée sans scanner tous les sous-documents dans le code client. Je pense que je ne peux pas mettre des fonctionnalités dans des documents séparés car j'ai besoin de mises à jour atomiques des fonctionnalités et mongodb ne supporte pas les transactions. – ixi

+1

Même si cela est vrai, il est plus facile de scanner les sous-documents du côté client car vous avez un type de structure de dictionnaire. – RameshVel

Questions connexes