2012-02-05 1 views
5

オブジェクトがネストされた配列を持つコレクションがmongodbにあるとします。私は配列の特定の要素の値に基づいてソートしたい。これは可能ですか?Mongoのネストされた配列内の要素でソートすることはできますか?

たとえば、ムービータイプ(アクション、コメディ、ロマンス)のコレクションとユーザーが送信した例がある場合、特定のユーザーが投稿したオブジェクトをすべて見つけることはできますか?映画の日付?

たとえば、 'Aaron'が送信したサンプルのうち、 'Aaron'が送信した年の順にソートされたすべてのタイプを検索したいとします。

ほとんどの場合、ソートのwhere節が好きです。

> db.movi​​es.find()。pretty();

{ 
    "_id" : ObjectId("4f2f07c1ec2cb81a269362c6"), 
    "type" : "action", 
    "examples" : [ 
     { 
      "title" : "Gladiator", 
      "year" : 2000, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Mission Impossiple", 
      "year" : 1996, 
      "submitter" : "Bill" 
     }, 
     { 
      "title" : "The Terminator", 
      "year" : 1984, 
      "submitter" : "Jane" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("4f2f07edaee5d897ea09f511"), 
    "type" : "comedy", 
    "examples" : [ 
     { 
      "title" : "The Hangover", 
      "year" : 2009, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Dogma", 
      "year" : 1999, 
      "submitter" : "Bill" 
     }, 
     { 
      "tile" : "Airplane", 
      "year" : 1980, 
      "submitter" : "Jane" 
     } 
    ] 
} 

> db.movi​​es.find({ 'examples.submitter': 'アロン'})ソート({ 'examples.year':1})かなり();。。文書は(予想通り)のコレクションの年によってソート返され

{ 
    "_id" : ObjectId("4f2f07edaee5d897ea09f511"), 
    "type" : "comedy", 
    "examples" : [ 
     { 
      "title" : "The Hangover", 
      "year" : 2009, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Dogma", 
      "year" : 1999, 
      "submitter" : "Bill" 
     }, 
     { 
      "tile" : "Airplane", 
      "year" : 1980, 
      "submitter" : "Jane" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("4f2f07c1ec2cb81a269362c6"), 
    "type" : "action", 
    "examples" : [ 
     { 
      "title" : "Gladiator", 
      "year" : 2000, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Mission Impossiple", 
      "year" : 1996, 
      "submitter" : "Bill" 
     }, 
     { 
      "title" : "The Terminator", 
      "year" : 1984, 
      "submitter" : "Jane" 
     } 
    ] 
} 

注 - 指定したユーザーが提出したものだけでソートする方法?私はnodejsのためのノードネイティブのmongoドライバを使用しています。

答えて

5

...特定のユーザーから送信されたものだけで並べ替える方法はありますか?

私はこれがあなたが望むようにうまくいかないと思います。

MongoDBでは、クエリはドキュメント全体を返します。次の問合せを実行すると、サブミッターが'Aaron'と一致するすべての文書が検索されます。

> db.movies.find({'examples.submitter': 'Aaron'}) 

'Aaron'は、理論的には同じ文書以内に2回一致しますが、一度だけ、その文書を返すことができることに注意してください。これはソートの問題を複雑にします。一つの文書が異なる年に'Aaron'ことにより、2つの事柄が含まれている場合

> db.movies.find({'examples.submitter': 'Aaron'}).sort({'examples.year': 1}) 

だからあなたは何を期待していますか?私たちはドキュメントをソートできるだけで、内部配列をクエリでソートすることはできません。

ここでの問題は、プロセス全体を複雑にする「オブジェクトの配列」を使用していることです。ソートの質問は、私たちが内側のオブジェクトに作用することができると仮定し、実際にはできません。

あなたが探しているものを提供するかもしれない新しいAggregation Frameworkを見てください。これは現在、不安定な支店の機能です。この時にケースの他の誰つまずくで

+0

私はそれをすることができるとは思わなかったが、それはショットの価値があると思った。あなたが言及した集約フレームワークが準備ができて安定しているように見えるように見えるので、私はそれを持ち上げてうれしいです。ありがとう! – Zugwalt

0

あなたのケースでは、server sideでevalを使用してカスタムソートを行う必要があります。並べ替えの具体例については、hereをご覧ください。あなたの比較関数は少し複雑になります。なぜなら、 "例"の配列とフィルターをサブミッターで渡す必要があるからです。

1

、私は次のようにインデックスを作成することで、同様の問題を解決することができた:、あなたがヒント(「索引名」)を使用して、このインデックスを使用するクエリを強制した場合

{'examples.submitter': 1, 'examples.year': 1} 

あなたの結果はインデックスの順に戻ります。

+0

あなたはそのファイルをどこに置くか/それがどのように機能するかについてもっと詳しく説明できますか?私はまた、ここの問題と非常に似た問題で苦労しています。 – ritmatter

+1

コレクションで.ensureIndexを使用する必要があります。通常、これはmongo db ideまたはコマンドラインで行います。 http://docs.mongodb.org/manual/reference/method/db.collection.ensureIndex/ヒントについては、mongodb http://docs.mongodb.org/manual/reference/operator/meta/hint/またはmongooseを使用してクエリのヒント関数を使用します。 query.hint({indexA:1、indexB:-1}) –

関連する問題