2014-11-14 149 views
1

我試圖將用戶之間的私人消息添加到我的數據模型中。我一直在兩種可能的方式之間來回切換。貓鼬私人聊天消息模型

1)每個用戶都有一個user_id,chat_id對的數組,對應於他們參與的聊天。聊天模型只存儲chat_id和消息數組。

2)不要與用戶存儲聊天,只要聊天模型存儲一對user_ids和消息數組。

選項(1)的問題是每當用戶加入或開始聊天時,我需要首先查看數組,以便用戶查看user_id,chat_id對是否已存在。然後在Chat中再次找到chat_id。如果它不存在,我需要在兩個不同的地方爲正在參與的用戶創建user_id,chat_id對。

使用選項(2)我將通過聊天模型搜索user_id1,user_id2對,如果我發現它,我完成了,如果沒有,我會爲該對創建一個新的聊天記錄並完成。

基於這個選項(2)似乎是處理這個問題的更好方法。然而,我遇到了一些問題,想要解決如何在聊天模型中輕鬆搜索用戶id的「對」。即,如果user_id以錯誤順序傳遞,即user_id2,user_id1,我如何確保我可以找到聊天記錄。在Mongoose中建模的最佳方式是什麼?

var chatSchema = mongoose.Schema({ 

    messages: [{ 
     text: { 
      type: String, 
      max: 2000 
     }, 
     sender: { 
      type: mongoose.Schema.Types.ObjectId, 
      ref: 'User' 
     } 
     }], 
    participant1: [{     
      type: mongoose.Schema.Types.ObjectId, 
      ref: 'User' 
     }] 
    participant2: [{     
      type: mongoose.Schema.Types.ObjectId, 
      ref: 'User' 
     }] 
}); 

如果是這樣的話,我將如何搜索參與者對?我能否以某種方式訂購參與者ID,以便他們總是參與者1 <參與者2例如,使搜索更簡單?

+1

我想你會希望發件人如何擁有它,然後而不是'參與者1','參與者2'等,只是做'參與者:[{type:mongoose.Schema.Types.ObjectId,ref:' User'}]'這將給你一個用戶數組,然後做一個搜索,你會做這樣的事情'Chat.find({參與者:{$ in:{「數組名稱」}},function(err,參與者){} – gmaniac 2014-11-14 19:21:22

+0

@gmaniac謝謝!我想我最終會做出與你所建議的非常相似的東西。$ in不起作用,因爲這樣做$或$但是$ all都可以用於這個我認爲。 – 2014-11-15 03:19:57

+0

很高興我可以幫助!如果你想更新你的問題,我們可以幫助你進一步或如果你找到你要找的答案並接受它 – gmaniac 2014-11-17 14:08:19

回答

3

一些建議。

首先 - 爲什麼存儲Participant1和2作爲數組?有一個特定發件人和一個(或多個)收件人(具體取決於是否需要羣組消息)。

考慮以下模式:

var ChatSchema = new Schema({ sender : { type : mongoose.Schema.Types.ObjectId, ref : 'User' }, messages : [ { message : String, meta : [ { user : { type : mongoose.Schema.Types.ObjectId, ref : 'User' }, delivered : Boolean, read : Boolean } ] } ], is_group_message : { type : Boolean, default : false }, participants : [ { user : { type : mongoose.Schema.Types.ObjectId, ref : 'User' }, delivered : Boolean, read : Boolean, last_seen : Date } ] });

此架構允許一個聊天文件來存儲所有信息,所有的參與者,並與每個消息,每個參與者都狀態。

布爾is_group_message是過濾哪些是直接/組消息,可能是客戶端查看或服務器端處理的簡短方法。直接消息顯然更容易用查詢方式工作,但兩者都非常簡單。

meta數組列出了單個消息的每個參與者的傳遞/讀取狀態等。如果我們不處理組消息,這不需要是一個數組,但我們是,所以這很好。

deliveredread屬性在主文檔(而不是元子文檔)上也是判斷最後一條消息是否被傳遞/讀取的簡便方法。它們在每次寫入文檔時都會更新。

該模式允許我們將關於聊天的所有內容存儲在一個文檔中。即使是羣組聊天。

+0

使用這種方法將使聊天效率低下分頁 – Maysara 2017-12-01 16:04:28

+0

@Maysara我已經一世基於這種方法爲生產聊天服務提供了更復雜的數據模式,如果需要的話,我可以花費一些時間並分享過程。任何選擇都有一定的折衷。讓每條消息單獨存儲然後再聚合它們看起來像是另一種對我來說沒有多大意義的選擇。 反向分頁在任何聊天系統中都比較少見,當它發生時,分頁到這個*實際*變得低效的地步實際上是非常罕見的。 – 2017-12-01 19:05:53

+0

@AugieGardner,我在建立一個聊天室,但是atm,我有一個會話模式和消息模式,他們有對話的ID。 您的模式看起來非常好,並防止來自MongoDB的多重查詢。 你能告訴我你正在談論的「更復雜」的模式嗎? – Hightline 2017-12-24 00:01:58