admin管理员组

文章数量:1026989

Let's say I have two users, "Matt" & "Kevin". Matt wants to message Kevin, by clicking a chat button to send Kevin a direct message a chat box boots up, he sends a message and Kevin receives it.

I generate the chat id by taking the person who sent it (Matt) and the person who received the message (Kevin) and concatenating it into an id.

var me = "Matt";
var user = "Kevin";
var uniqueChatID = me+user;

As I save the message server side (with mongoDB) the message object has a chatID of MattKevin. So now when I want to get back to that chat I can pull in all messages with the chatID of MattKevin.

This works fine, until Kevin wants to boot up a chat with Matt, then the id bees KevinMatt. Now I am referencing a different chat, it's backwards. So If I want to pass uniqueChatID to get the messages it will pull a different set.

var me = "Kevin";
var user = "Matt";
var uniqueChatID = me+user;

So I am curious how can I set this up a bit better so that my program knows, ok Matt and Kevin have a chat, so if Matt messages Kevin it pulls in their chat or visa versa, Kevin messages Matt and it gets the same messages?

Let's say I have two users, "Matt" & "Kevin". Matt wants to message Kevin, by clicking a chat button to send Kevin a direct message a chat box boots up, he sends a message and Kevin receives it.

I generate the chat id by taking the person who sent it (Matt) and the person who received the message (Kevin) and concatenating it into an id.

var me = "Matt";
var user = "Kevin";
var uniqueChatID = me+user;

As I save the message server side (with mongoDB) the message object has a chatID of MattKevin. So now when I want to get back to that chat I can pull in all messages with the chatID of MattKevin.

This works fine, until Kevin wants to boot up a chat with Matt, then the id bees KevinMatt. Now I am referencing a different chat, it's backwards. So If I want to pass uniqueChatID to get the messages it will pull a different set.

var me = "Kevin";
var user = "Matt";
var uniqueChatID = me+user;

So I am curious how can I set this up a bit better so that my program knows, ok Matt and Kevin have a chat, so if Matt messages Kevin it pulls in their chat or visa versa, Kevin messages Matt and it gets the same messages?

Share Improve this question asked Jul 23, 2015 at 5:09 Michael Joseph AubryMichael Joseph Aubry 13.5k16 gold badges77 silver badges141 bronze badges 2
  • Sort them alphabetically? – brandonscript Commented Jul 23, 2015 at 5:10
  • Ok, so client side generate the ID by alphabetic letters? – Michael Joseph Aubry Commented Jul 23, 2015 at 5:11
Add a ment  | 

2 Answers 2

Reset to default 5

Sort them alphabetically:

var me = "Kevin";
var user = "Matt";
var uniqueChatID = [me, user].sort().join('');

That said, while this technically works, I'd remend you do a little housekeeping - ensure they're always lowercase, and ensure on your db that you enforce unique usernames. Or, I'd even suggest giving the user a unique identifier (like a UUID) and use that instead to create the UCID:

var me = CurrentUser.uuid(); // 8cb3ebb8-30f9-11e5-a151-feff819cdc9f
var targetUser = Chat.targetUser(); // Matt: 9bc1ef9c-6719-4041-afd3-c5b87c90690d
var uniqueChatID = [me, targetUser].sort().join(',');
// 8cb3ebb8-30f9-11e5-a151-feff819cdc9f,9bc1ef9c-6719-4041-afd3-c5b87c90690d

And lastly, if your db supports relationships or connections, your best option is to separate chat table/collection for each chat and "connect" (or create a relationship) between both users and the chat. Then the next time you go and load it up, the connection will lead you to a unique chat that's connected to both users.

I think you approach is too plex. Furthermore, it looks like you want to embed the individual chat messages into the document bearing the created _id. The problem here is that there is a 16 MB size limit on BSON documents at the time of this writing. Upon reaching this limit, your users simply could not municate any more. Increasing the size of documents may also lead to frequent document relocations, which is a very costly operation unless you use the new WiredTiger storage engine introduced in version 3.0 of MongoDB.

So we need a more scalable approach.

Here is how I would do it:

User:

{
  _id: "Kevin",
  email: "[email protected]"
  /* Put further user details as you see fit*/
}

Message:

{
  _id: new ObjectId(),
  from: "Kevin",
  /* You might want to have multi-person chats, hence the array */
  to: ["Matt"],
  ts: new ISODate(),
  message: "Hi, Matt!"
}

Index:

db.messages.ensureIndex({from:1,to:1,ts:1})

Query for reconstructing all messages a user received:

var user = "Matt"
db.messages.find({"to": user}).sort({ts:1})

Now you can iterate over the result set and open a chat window for each "from" you find.

Query for reconstructing a defined chat

var user = "Matt"
var sender = "Kevin"
db.messages.find({"from": sender, "to":user}).sort({ts:1})

will give you all messages sent to Matt by Kevin, ordered by time. Since both queries should utilize the index, they should be pretty fast. You can use .limit(x) to query only the last x messages sent to user.

With this approach, you don't need an artificial _id, the index created allows you to do every query related to the participants efficiently and the messages can be sorted in order. Because each message is saved individually and does not change any more, you can store an almost indefinite number of messages and bypass the document relocation problem.

Let's say I have two users, "Matt" & "Kevin". Matt wants to message Kevin, by clicking a chat button to send Kevin a direct message a chat box boots up, he sends a message and Kevin receives it.

I generate the chat id by taking the person who sent it (Matt) and the person who received the message (Kevin) and concatenating it into an id.

var me = "Matt";
var user = "Kevin";
var uniqueChatID = me+user;

As I save the message server side (with mongoDB) the message object has a chatID of MattKevin. So now when I want to get back to that chat I can pull in all messages with the chatID of MattKevin.

This works fine, until Kevin wants to boot up a chat with Matt, then the id bees KevinMatt. Now I am referencing a different chat, it's backwards. So If I want to pass uniqueChatID to get the messages it will pull a different set.

var me = "Kevin";
var user = "Matt";
var uniqueChatID = me+user;

So I am curious how can I set this up a bit better so that my program knows, ok Matt and Kevin have a chat, so if Matt messages Kevin it pulls in their chat or visa versa, Kevin messages Matt and it gets the same messages?

Let's say I have two users, "Matt" & "Kevin". Matt wants to message Kevin, by clicking a chat button to send Kevin a direct message a chat box boots up, he sends a message and Kevin receives it.

I generate the chat id by taking the person who sent it (Matt) and the person who received the message (Kevin) and concatenating it into an id.

var me = "Matt";
var user = "Kevin";
var uniqueChatID = me+user;

As I save the message server side (with mongoDB) the message object has a chatID of MattKevin. So now when I want to get back to that chat I can pull in all messages with the chatID of MattKevin.

This works fine, until Kevin wants to boot up a chat with Matt, then the id bees KevinMatt. Now I am referencing a different chat, it's backwards. So If I want to pass uniqueChatID to get the messages it will pull a different set.

var me = "Kevin";
var user = "Matt";
var uniqueChatID = me+user;

So I am curious how can I set this up a bit better so that my program knows, ok Matt and Kevin have a chat, so if Matt messages Kevin it pulls in their chat or visa versa, Kevin messages Matt and it gets the same messages?

Share Improve this question asked Jul 23, 2015 at 5:09 Michael Joseph AubryMichael Joseph Aubry 13.5k16 gold badges77 silver badges141 bronze badges 2
  • Sort them alphabetically? – brandonscript Commented Jul 23, 2015 at 5:10
  • Ok, so client side generate the ID by alphabetic letters? – Michael Joseph Aubry Commented Jul 23, 2015 at 5:11
Add a ment  | 

2 Answers 2

Reset to default 5

Sort them alphabetically:

var me = "Kevin";
var user = "Matt";
var uniqueChatID = [me, user].sort().join('');

That said, while this technically works, I'd remend you do a little housekeeping - ensure they're always lowercase, and ensure on your db that you enforce unique usernames. Or, I'd even suggest giving the user a unique identifier (like a UUID) and use that instead to create the UCID:

var me = CurrentUser.uuid(); // 8cb3ebb8-30f9-11e5-a151-feff819cdc9f
var targetUser = Chat.targetUser(); // Matt: 9bc1ef9c-6719-4041-afd3-c5b87c90690d
var uniqueChatID = [me, targetUser].sort().join(',');
// 8cb3ebb8-30f9-11e5-a151-feff819cdc9f,9bc1ef9c-6719-4041-afd3-c5b87c90690d

And lastly, if your db supports relationships or connections, your best option is to separate chat table/collection for each chat and "connect" (or create a relationship) between both users and the chat. Then the next time you go and load it up, the connection will lead you to a unique chat that's connected to both users.

I think you approach is too plex. Furthermore, it looks like you want to embed the individual chat messages into the document bearing the created _id. The problem here is that there is a 16 MB size limit on BSON documents at the time of this writing. Upon reaching this limit, your users simply could not municate any more. Increasing the size of documents may also lead to frequent document relocations, which is a very costly operation unless you use the new WiredTiger storage engine introduced in version 3.0 of MongoDB.

So we need a more scalable approach.

Here is how I would do it:

User:

{
  _id: "Kevin",
  email: "[email protected]"
  /* Put further user details as you see fit*/
}

Message:

{
  _id: new ObjectId(),
  from: "Kevin",
  /* You might want to have multi-person chats, hence the array */
  to: ["Matt"],
  ts: new ISODate(),
  message: "Hi, Matt!"
}

Index:

db.messages.ensureIndex({from:1,to:1,ts:1})

Query for reconstructing all messages a user received:

var user = "Matt"
db.messages.find({"to": user}).sort({ts:1})

Now you can iterate over the result set and open a chat window for each "from" you find.

Query for reconstructing a defined chat

var user = "Matt"
var sender = "Kevin"
db.messages.find({"from": sender, "to":user}).sort({ts:1})

will give you all messages sent to Matt by Kevin, ordered by time. Since both queries should utilize the index, they should be pretty fast. You can use .limit(x) to query only the last x messages sent to user.

With this approach, you don't need an artificial _id, the index created allows you to do every query related to the participants efficiently and the messages can be sorted in order. Because each message is saved individually and does not change any more, you can store an almost indefinite number of messages and bypass the document relocation problem.

本文标签: javascriptChat application how to generate an id for a particular chatStack Overflow