2012-01-17 22 views
1

文書構造の例は次のとおりです。PHPでMongoDBのネストされた配列検索

{ 
    "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", 
    } 
    } 
} 

私は支払いが「30」未満であるすべてのものを「訪問」の情報(および「名前」に相当する)をリストにしたいです。

「お支払い」<「30」以外の訪問は印刷しません。そのようなクエリは可能ですか、またはまず検索を使用してドキュメント全体を取得し、そのような訪問を選択するためにPHPを使用する必要がありますか?

答えて

18

例のドキュメントでは、 "payment"値は文字列として与えられています。 $ ltコマンド。この応答のために、私は整数に変換しました。

MongoDBではワイルドカードクエリが不可能なので、特定のドキュメント構造では、サブドキュメントのキー(0,1,2など)を知っていなければなりません。たとえば、次のクエリは動作します:

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

しかし、

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

、この場合では動作しません、と

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

も結果を返しません。

埋め込まれた「訪問」の文書を照会できるようにするために、あなたは、文書の構造を変更し、アレイまたは埋め込まれた文書に「訪問」を作り、そのような必要があります。

> 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" 
     } 
    ] 
} 

今あなたが照会することができます「訪問」に埋め込まれた文書のすべて:

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

詳細については、ドット表記上のモンゴのドキュメントを参照してください。

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

質問の2番目の部分に戻ります。埋め込みドキュメントの条件付きサブセットのみを返すことはできません。

いずれのドキュメント形式でも、クエリに一致するサブドキュメントのみを含むドキュメントを返すことはできません。サブ文書の1つが照会と一致すると、文書全体が照会と一致し、それが戻されます。

> 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" 
     } 
    ] 
} 

しかし、我々はいくつかの条件付き検索を持つことはできません:私たちはそうのように埋め込まれた文書の一部を返すことができ

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

「フィールドのサブセットを取得」モンゴドキュメントを1として

サブ文書。我々が得ることができる最も近い$スライス演算子であるが、これは条件付きではなく、あなたが最初の配列内の各サブ文書の場所を知っている必要があります:アプリケーションのために

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

クエリに一致する埋め込みドキュメントのみを表示するには、プログラムで実行する必要があります。

+0

ありがとうございました。私は完全なドキュメントから情報を取得するためにPHPを使用しなければならないと思います。 – pun

1

あなたは試みることがあります。

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

しかしvisitsがオブジェクトであるため、それがうまくいくかどうかはわかりません。あなたが投稿したものから判断すると、配列に転送される可能性があります(または数値プロパティ名が混乱の原因となるため)。

+0

しかし、これは、「支払いのための訪問を含め、 "支払い" < "30" を含む文書全体が返され"> 30ありがとうございます – pun

+0

はい、支払額が30を超える文書のみは含まれませんが、これが最善の方法です。 –

0

トライ - db.test2.find({ "visits.payment": "35"})