2012-01-17 7 views
1

documents Exemple de structure est:MongoDB recherche tableau imbriqué

{ 
    "dob": "12-13-2001", 
    "name": "Kam", 

    "visits": { 
    "0": { 
     "service_date": "12-5-2011", 
     "payment": "40", 
     "chk_number": "1234455", 
    }, 
    "1": { 
     "service_date": "12-15-2011", 
     "payment": "45", 
     "chk_number": "3461234", 
    }, 
    "2": { 
     "service_date": "12-25-2011", 
     "payment": "25", 
     "chk_number": "9821234", 
    } 
    } 
} 


{ 
    "dob": "10-01-1998", 
    "name": "Sam", 

    "visits": { 
    "0": { 
     "service_date": "12-5-2011", 
     "payment": "30", 
     "chk_number": "86786464", 
    }, 
    "1": { 
     "service_date": "12-15-2011", 
     "payment": "35", 
     "chk_number": "45643461234", 
    }, 
    "2": { 
     "service_date": "12-25-2011", 
     "payment": "20", 
     "chk_number": "4569821234", 
    } 
    } 
} 

En PHP je veux la liste de toutes ces informations « visites » (et « nom » correspondant) dont le paiement est inférieur à « 30 ».

Je veux imprimer seulement les visites avec "paiement" < "30" pas d'autres. Est-ce qu'une telle requête est possible, ou dois-je d'abord obtenir le document entier en utilisant la recherche, puis utiliser PHP pour sélectionner de telles visites?

Répondre

18

Dans le document d'exemple, les valeurs de "paiement" sont données comme des chaînes qui peuvent ne pas fonctionner comme prévu avec le Commande $ lt Pour cette réponse, je les ai convertis en entiers.

Les requêtes génériques ne sont pas possibles avec MongoDB, donc avec la structure de document donnée, la clé (0,1,2, etc.) du sous-document doit être connue. Par exemple, la requête suivante fonctionnera:

> db.test.find({"visits.2.payment":{$lt:35}}) 

Cependant,

> db.test.find({"visits.payment":{$lt:35}}) 

ne fonctionnera pas dans ce cas, et

> db.test.find({"visits.*.payment":{$lt:35}}) 

également retourné aucun résultat.

Afin de pouvoir interroger les documents « visites » intégrées, vous devez modifier la structure de votre document et faire des « visites » dans un tableau ou des documents intégrés, comme ceci:

> db.test2.find().pretty() 
{ 
    "_id" : ObjectId("4f16199d3563af4cb141c547"), 
    "dob" : "10-01-1998", 
    "name" : "Sam", 
    "visits" : [ 
     { 
      "service_date" : "12-5-2011", 
      "payment" : 30, 
      "chk_number" : "86786464" 
     }, 
     { 
      "service_date" : "12-15-2011", 
      "payment" : 35, 
      "chk_number" : "45643461234" 
     }, 
     { 
      "service_date" : "12-25-2011", 
      "payment" : 20, 
      "chk_number" : "4569821234" 
     } 
    ] 
} 

Maintenant, vous pouvez interroger tous les documents intégrés dans les "visites":

> db.test2.find({"visits.payment":{$lt:35}}) 

pour plus d'informations, s'il vous plaît se référer à la documentation sur la notation dot mongo:

http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

Passons maintenant à la deuxième partie de votre question: il n'est pas possible de renvoyer uniquement un sous-ensemble conditionnel de documents incorporés.

Avec l'un ou l'autre format de document, il n'est pas possible de renvoyer un document contenant UNIQUEMENT les sous-documents correspondant à la requête. Si l'un des sous-documents correspond à la requête, le document entier correspond à la requête et sera renvoyé.

Selon le Mongo document « Récupération d'un sous-ensemble des champs »

http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields

Nous pouvons retourner des parties de documents intégrés comme ceci:

> db.test2.find({"visits.payment":{$lt:35}},{"visits.service_date":1}).pretty() 
{ 
    "_id" : ObjectId("4f16199d3563af4cb141c547"), 
    "visits" : [ 
     { 
      "service_date" : "12-5-2011" 
     }, 
     { 
      "service_date" : "12-15-2011" 
     }, 
     { 
      "service_date" : "12-25-2011" 
     } 
    ] 
} 

Mais nous ne pouvons pas avoir la récupération conditionnelle de certaines sous-documents. Le plus proche que nous pouvons obtenir est l'opérateur de la tranche de $, mais ce n'est pas conditionnelle, et vous devez d'abord connaître l'emplacement de chaque sous-document dans le tableau:

http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields#RetrievingaSubsetofFields-RetrievingaSubrangeofArrayElements

Pour l'application pour afficher uniquement les documents incorporés correspondant à la requête, il faudra le faire par programmation.

+0

Merci Marc pour l'explication .. Je suppose que je vais devoir utiliser PHP pour récupérer des informations du document complet. – pun

1

Vous pouvez essayer:

$results = $mongodb->find(array("visits.payment" => array('$lt' => 30))); 

Mais je ne sais pas si cela fonctionnera depuis visits est un objet. A partir de ce que vous avez posté, BTW pourrait être transféré vers array (ou devrait, puisque les noms de propriétés numériques tendent à créer une confusion)

+0

Mais cela renverra le document entier contenant "paiement" < "30", y compris les visites pour lesquelles « paiement "> 30. Merci pour votre aide – pun

+0

Oui, mais n'inclut pas les documents qui ont seulement un paiement> 30, c'est le mieux que vous pouvez faire. –

0

essayer - db.test2.find ({ "visits.payment": "35"})

Questions connexes