2017-06-23 21 views
-1

質問を参照してください。Match conditions and latest date from array良い解決策がNeil Lunnによって提供されています。複雑なMongoクエリ

db.chat.find().pretty().limit(2) 
{ 
    "_id" : ObjectId("593921425ccc8150f35e7662"), 
    "user1" : 1, 
    "user2" : 2, 
    "messages" : [ 
     { 
      "sender" : 1, 
      "datetime" : ISODate("2017-05-01T00:00:00Z"), 
      "body" : "hiii 120" 
     }, 
     { 
      "sender" : 1, 
      "datetime" : ISODate("2017-06-01T00:00:00Z"), 
      "body" : "hiii 121" 
     }, 
     { 
      "sender" : 2, 
      "datetime" : ISODate("2017-06-10T00:00:00Z"), 
      "body" : "hiii 2" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("593921425ccc8150f35e7663"), 
    "user1" : 1, 
    "user2" : 3, 
    "messages" : [ 
     { 
      "sender" : 1, 
      "datetime" : ISODate("2017-05-02T00:00:00Z"), 
      "body" : "hiii 130" 
     }, 
     { 
      "sender" : 1, 
      "datetime" : ISODate("2017-06-02T00:00:00Z"), 
      "body" : "hiii 131" 
     }, 
     { 
      "sender" : 3, 
      "datetime" : ISODate("2017-06-10T00:00:00Z"), 
      "body" : "hiii 2" 
     } 
    ] 
} 

ここで問題となるのは、messages.sender = datetimeで1桁のユーザーのリストです。

すなわち 出力:

{ 
     "sender" : 1, 
     "receiver" : 2, 
     "datetime" : ISODate("2017-06-02T00:00:00Z"), 
     "body" : "hiii 131" 
    }, 
    { 
     "sender" : 1, 
     "receiver" : 2, 
     "datetime" : ISODate("2017-06-01T00:00:00Z"), 
     "body" : "hiii 121" 
    },      
    { 
     "sender" : 1, 
     "receiver" : 3, 
     "datetime" : ISODate("2017-05-02T00:00:00Z"), 
     "body" : "hiii 130" 
    }, 
    { 
     "sender" : 1, 
     "receiver" : 3, 
     "datetime" : ISODate("2017-05-01T00:00:00Z"), 
     "body" : "hiii 120" 
    }, 

は、多くのクエリを試みたが、所望の出力を得ることができません。

説明出力:あなたが供給されたデータでテスト

db.chat.find().pretty().limit(2) 
{ 
    "_id" : ObjectId("593921425ccc8150f35e7662"), 
    "user1" : 1, 
    "user2" : 2, 
    "messages" : [ 
     { 
      "sender" : 1, 
      **"datetime" : ISODate("2017-05-01T00:00:00Z"),**--- message will apear at No4 as sender=1. Also we need data of user1/user2 which is not equal to 1 i.e 2. 
      "body" : "hiii 120" 
     }, 
     { 
      "sender" : 1, 
      **"datetime" : ISODate("2017-06-01T00:00:00Z"),**--- message will apear at No2 as sender=1. Also we need data of user1/user2 which is not equal to 1 i.e 2. 
      "body" : "hiii 121" 
     }, 
     { 
      "sender" : 2, 
      "datetime" : ISODate("2017-06-10T00:00:00Z"), 
      "body" : "hiii 2" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("593921425ccc8150f35e7663"), 
    "user1" : 1, 
    "user2" : 3, 
    "messages" : [ 
     { 
      "sender" : 1, 
      **"datetime" : ISODate("2017-05-02T00:00:00Z"),** --- message will apear at No3 as sender=1. Also we need data of user1/user2 which is not equal to 1 i.e 3. 
      "body" : "hiii 130" 
     }, 
     { 
      "sender" : 1, 
      **"datetime" : ISODate("2017-06-02T00:00:00Z"),** --- message will apear at top as sender=1 and of max datetime. Also we need data of user1/user2 which is not equal to 1 i.e 3. 
      "body" : "hiii 131" 
     }, 
     { 
      "sender" : 3, 
      "datetime" : ISODate("2017-06-10T00:00:00Z"), 
      "body" : "hiii 2" 
     } 
    ] 
} 
+0

によるソートの必要性についてコメントを読んでいるので、$sortを追加します。これは、配列内のコンテンツだけですか?それには何かが行われるはずですか?データをどのように選択するかについて詳しく説明できますか? –

+0

はい配列内の内容+送信者ではない他のユーザー...最も重要なのは、メッセージのすべての一致する行の日時に基づいて並べ替える必要があります.... –

+0

もう少し説明的なものを教えてください。あなたは基本的に質問に2つの文章を書いた。それ以上の説明が必要です。たとえば、出力にない項目がソースにあります。読者は出力がどのように達成されているかを理解する必要があります。 –

答えて

1

。これは動作します:

db.getCollection('test').aggregate([ 
{$unwind:"$messages"}, 
{$match : {"messages.sender" : 1}}, 
{$project:{ 
    "_id" : 0, 
    "sender" : "$messages.sender", 
    "datetime" : "$messages.datetime", 
    "body" : "$messages.body", 
    "receiver" : {$cond : {if: { $eq : ["$messages.sender","$user1"]}, then: "$user2", else: "$user1"}}, 
    } 
}, 
{$sort : {"datetime" : 1}} 
]) 

$unwindは、すべてのメッセージのために別々のオブジェクトを作成します。

$matchはあなたが要求された形式にデータを回す送信者= 1

$project持つものだけを保持します。

送信者に応じて受信者をユーザー1またはユーザー2にしたいので、$condステートメントが必要です。

EDIT: 私はちょうど私がそれを得ることはありません日時

+0

コストのかかる操作として巻き戻しを使わずにこれを行うことはできますか? –

+0

もっと多くの作業が可能かもしれません。しかし、おそらく時間が問題であれば、提案された成果は問題です。おそらく、この問題はアプリケーション側でデータベースよりもよく解決されるでしょうか? –