2012-01-12 11 views
19

私は1人以上のサービスに加入しているユーザーの集まりを持っています。各サービスには、ユーザーがそのサービスに対して持っているクレジット数を含むいくつかのメタデータがあります。Mongodbドット表記ワイルドカード?

サービスオブジェクトのキーが何であるかを知る方法がないと、サービスのクレジットが50未満のすべてのユーザーオブジェクトを見つけるにはどうすればよいですか?

概念的に、それは動作しません。このような何か、次のようになります場合には、それはないですが、

{ 
_id: 4f0ea25072139e4d2000001f, 
services : { 
    a : { credits : 100, score : 2000 }, 
    b : { credits : 200, score : 300 }, 
    c : { credits : 10, score : 1300 } 
    } 
}, 
{ 
_id: 4f0ea25072139e4d2000001f, 
services : { 
    f : { credits : 68, score : 14 }, 
    q : { credits : 1000, score : 102 }, 
    z : { credits : 59, score : 352 } 
    } 
} 

私がやりたいことのもう一つの例:

db.users.find({services.*.credits : {$lt : 50}}) 

ユーザーコレクションここで説明されています:http://www.mongodb.org/display/DOCS/Advanced+Queries#comment-346075854

答えて

-1

サービスオブジェクトを配列に入れるともっと簡単になると思いますので、$elemMatch、のように:

db.coll.find({services: {$elemMatch : {credits: {$lt: 50}}}}); 

結果:

{ 
    services : [ 
    {key: "a" , credits : 100, score : 2000 }, 
    {key: "b", credits : 200, score : 300 }, 
    {key: "c", credits : 10, score : 1300 } 
    ] 
} 

{ 
    _id: 4f0ea25072139e4d2000001f, 
    services : [ 
    {key: "f", credits : 68, score : 14 }, 
    {key: "q", credits : 1000, score : 102 }, 
    {key: "z", credits : 59, score : 352 } 
    ] 
} 

次にあなたが書くでしょうクエリは次のようになります

{ "_id" : ObjectId("4f0f2be07561bf94ea47eec4"), "services" : [ { "key" : "a", "credits" : 100, "score" : 2000 }, { "key" : "b", "credits" : 200, "score" : 300 }, { "key" : "c", "credits" : 10,  "score" : 1300 } ] } 
+0

私はちょうど配列を使用するために私たちのスキーマを変更してしまうんでした:

は、クエリが$を使用してください。私は$ elemMatchを使用することができましたが、1つの条件を満たすだけで済むので、できました: 'db.users.find({services.credits:{$ lt:50}})' – stuporglue

+9

-1これは質問に対する答えではありません。誰もが、彼らが作業しているデータのスキーマを変更する能力を持っているわけではありません。この質問には未回答のままです。 – CommaToast

+0

OK私は自分でそれに答えました。それを行う方法が見つかりました。以下に掲示される。 – CommaToast

1

私はしないでくださいあなたがスキーマを使用してこれを達成する方法を知っているeを使用します。あなたが配列としてオブジェクトを悪用しようとしているようです。 servicesが配列(それがなければならないことを、複数のヒントが)だった場合、あなたは単に

db.users.find({"services.credits" : { $lt : 50 }}); 

を問い合わせることができたり、単一の配列要素に複数の条件を一致させる必要がある場合$elemMatchを使用しています。

+0

私が本当に望んだのは、連想配列で、同じサービスIDに対して2つの配列要素を持つことを妨げていました。私たちのユーザは決して '{services:[{service:f、credits 50}、{service:f、credits:60}}}'に終わるべきではありません。連想配列はこれを強制し、ルックアップの90%を自明にします。 通常の配列を使用すると、クエリを実行する前にまず配列を検索して、サービス配列に追加するか要素を見つけて更新する必要があるかどうかを確認する必要があります。 – stuporglue

+0

ほとんどすべての一貫性チェックはコードで行う必要があります。連想配列の場合も同様です。MongoDBは埋め込みドキュメントの制約をサポートしていません:http://waistcode.net/blog/unique-array-keys-in-mongodb、つまり、オブジェクトは「自分自身を侵害することはできません。 – mnemosyn

+0

これは質問に対する答えではありません。上記の@ stuporglueのコメントは、彼のやり方と同じように自分のデータモデルを作成した、完全に有効で大きな理由を説明しています。私たちのデータモデルが私たちのやり方で行われたのと同じ理由です。そして、私はまだこの質問への答えが必要です。彼らが答えを知らない、または人々を悪用することなどを批判していると言っている人は、単に非生産的です。 – CommaToast

15

これはあなたの質問に対する実際の回答です。

サービスオブジェクトのキーが何であるかを知る方法がない場合、サービスのクレジットが50未満のすべてのユーザーオブジェクトを見つける方法は次のとおりです。

db.users.find({ 
    $where: function() { 
     for (var index in this.services) 
      if (this.services[index].credits < 50) 
       return this; 
    } 
}); 
+1

あなたの「クエリ」は完全にインデックスサポートを欠いています。このようなデータ構造を使用する理由はありません。索引をシミュレートできない場合は、コレクションのスキャンを毎回実行しています。コレクション全体をRAMにロードしてスキャンするだけで、JavaScriptで簡単に実行できます。 – mnemosyn

+7

彼は、「サービスオブジェクトのキーが何であるかを知る方法がないと、何らかのサービスに対して50クレジット未満のユーザーオブジェクトをすべて見つけるにはどうすればよいでしょうか?私は彼の質問に答えました。私は答えではなかったので、回答者だけを回答者にダウンボティングしませんでした。彼らは明らかにあなたができるときに "あなたはそれをすることはできません/してはいけません"と言っている人々でした。そして、それは純粋にあなたがすべきかどうかについての意見の問題です。私は、「このようなデータ構造を使用する理由はない」と同意します...そうする大きな理由がたくさんあります。あなたがそれらを知らないので、本当に私のせいでもない。 – CommaToast

+4

私は人の担当者を見ていない私はちょうど答えを読んでいます。私はあなたがMongoDBについてもっと知っているとは思っていません。しかし、それが質問された質問に対する答えでないなら、私はそれをdownvoteする義務があります。私は、あなたが高い担当者を持っているので、単純にそうしないつもりはありません。誰かに何かをする方法がないと言って、実際にそこにいるときは、冷たくない。あなたがそのポイントを見ていないという理由だけで、データ構造が無意味であると人々に伝えることは、どちらもクールではありません。たぶん、彼らはあなたが単に理解していないそれを使用する大きな理由があります。たぶんあなたはポイントが何かを尋ねた場合、あなたは学ぶかもしれません。 – CommaToast

関連する問題