2016-11-21 10 views
0

私はMongo 3.2のデータベースを会話の集まりに持っています。各要素は、以下のようになります。MongoDBは最初の項目を返すだけです

{ 
"_id" : ObjectId("582e9f85160238a44ef0bfbd"), 
"conversation_id" : 39, 
"owner_id" : 8, 
"title" : "Title", 
"recipients" : 1, 
"last_modified" : "2016-10-28 06:21:35", 
"locked" : 0, 
"recipients_details" : [ 
    { 
     "user_id" : 1, 
     "last_message" : "2016-10-28 06:21:35" 
    }, 
    { 
     "user_id" : 8, 
     "last_message" : "2016-10-28 06:14:00" 
    } 
] 
} 

私はいくつかののuser_idが含まれている会話に最後のメッセージを投稿されたすべてのユーザーを取得したいです。例として、ユーザー#8のすべての会話を取得したい場合、上記のJSONの 'recipients_details'は、メッセージが最後であるためuser_id = 1のレコードを1つだけ含める必要があります。私はこのコードを試してみたが、それはすべてのレコードを与え、それを巻き戻すこと(この文で)ソリューションではありません。

db.conversations.aggregate([ 
    {$match:{'recipients_details.user_id':1}}, 
    {$sort:{'last_modified':-1}}, 
    {$project:{_id:1,last_modified:1,recipients_details:1}} 
]) 

UPD:構造は2つのMySQLのテーブル(会話と受信者(conversation_idから移行されました、 user_id,message_posted))。私は、このSQLのアナログを見つけたい:

SELECT * FROM `recipients` WHERE `conversation_id` IN (SELECT `conversation_id` FROM `recipients` WHERE `user_id` = 1) AND `user_id` <> 1 GROUP BY `conversation_id` ORDER BY `message_posted` DESC 

、結果として私が持っている:

  conversation_id user_id message_posted  
     --------------- ------- --------------------- 
     40  164 2016-11-01 12:13:23 
     39  8 2016-10-28 06:14:00 
     27  65 2016-10-26 14:26:59 
     23  65 2016-10-26 14:23:59 
     24  62 2016-10-26 08:44:14 
     20  62 (NULL)    
     25  76 (NULL)    
     42  64 (NULL)    
     43  65 (NULL)    
     44  68 (NULL)    
+0

IIUC last is max 'last_message' right? – styvane

+0

これを正しく取得した場合、特定の 'user_id'に属している(last_messageでソートされた)会話の最後のメッセージを投稿するユーザーのセットを探したいですか?この場合、 '{'recipients_details.user_id':1}' – hyades

+0

にマッチングしているのはそれだけです。ここに私が持っているものと、私が見ているものの[貼り付け](http://pastebin.com/F6ZCErAU)があります。会話に投稿した最後のユーザーを見つけたいだけですが、すべてのユーザーではなく、現在のユーザーのみを探しています。 – Iworb

答えて

1

あなたの生データを見た後、あなたが最初recipients_details.user_id:8と後が含まれているそれらの文書を見つけるように思えますrecipients_details配列では、last_message値をソートして最初の値だけを取得したいと考えています。このためには、$setDifference$filterを使用するためにmongo配列セット操作を使用する必要があります。まず、一致するusers_idをフィルタリングしてから、配列の差と最後のアンワインド結果のみを取得してすべての結果をグループ化します。以下のクエリを確認してください:

db.collectionName.aggregate({ 
    "$match": { 
    "recipients_details.user_id": { 
     "$in": [8] 
    } 
    } 
}, { 
    "$project": { 
    "filter": { 
     "$setDifference": ["$recipients_details", { 
      "$filter": { 
       "input": "$recipients_details", 
       "as": "recp", 
       "cond": { 
        "$eq": ["$$recp.user_id", 8] 
       } 
      } 
     }] 
    }, 
    "conversation_id": 1, 
    "owner_id": 1, 
    "title": 1, 
    "recipients": 1, 
    "last_modified": 1, 
    "locked": 1 
    } 
}, { 
    "$unwind": "$filter" 
}, { 
    "$sort": { 
    "filter.last_message": -1 
    } 
}, { 
    "$group": { 
    "_id": "$_id", 
    "conversation_id": { 
     "$first": "$conversation_id" 
    }, 
    "owner_id": { 
     "$first": "$owner_id" 
    }, 
    "title": { 
     "$first": "$title" 
    }, 
    "recipients": { 
     "$first": "$recipients" 
    }, 
    "last_modified": { 
     "$first": "$last_modified" 
    }, 
    "locked": { 
     "$first": "$locked" 
    }, 
    "recipients_details": { 
     "$first": { 
      "user_id": "$filter.user_id", 
      "last_message": "$filter.last_message" 
     } 
    } 
    } 
}).pretty() 
+0

結果としてユーザー#8のuser_idを置き換えようとすれば、ユーザー#1の代わりに彼のためのrecipient_detailsも得られます。 {"_id":ObjectId( "582e9f85160238a44ef0bfbd")、 "recipients_details":[{"user_id":8、 "last_message": "2016-10-28 06:14:00"}]} – Iworb

+0

説明できませんでしたmoreまたはper @hyades commentとして 'last_message'ソートされたデータだけを探したいのですが、' user_id'とマッチした理由は何ですか? – Yogesh

+0

それは私が期待している結果です:1. "recipients_details"の中でユーザー#8が会話を見つけます。 2.取得したデータからユーザー#8を削除します。 3. "recipients_details"には、最後のメッセージを投稿したユーザーが1人だけ残っています(誰のlas_messageもnullの場合はすべてのユーザー) – Iworb

関連する問題