package main
import (
"encoding/json"
"fmt"
"strconv"
)
const (
DB_NAME = "chat"
TABLE_NAME = "person_log"
)
type PersonalChatLogMsg struct {
Key string
ChatInfo []*PersonalChatLog
}
type PersonalChatLog struct {
LogId int64
Talker int64
TargetId int64
Content string
IsRead bool
}
func GetChatLogKey(talkId, targetId int64) string {
var key string
if talkId > targetId {
key = fmt.Sprintf("%d_%d", targetId, talkId)
} else {
key = fmt.Sprintf("%d_%d", talkId, targetId)
}
return key
}
func AddChatLog(info *PersonalChatLog) { //增加聊天记录
mongo, err := mgo.Dial("mongodb://root:MongoDB@127.0.0.1:27017") // 建立连接
defer mongo.Close()
if err != nil {
panic(err)
}
col := mongo.DB(DB_NAME).C(TABLE_NAME) //选择数据库和集合
var obj *PersonalChatLogMsg
key := GetChatLogKey(info.Talker, info.TargetId) //按id排序组合字符串key
err1 := col.Find(bson.M{"key": key}).One(&obj)
if err1 != nil && err1 != mgo.ErrNotFound {
panic(err1)
}
if err1 == mgo.ErrNotFound {
obj = &PersonalChatLogMsg{
Key: key,
ChatInfo: []*PersonalChatLog{info},
}
col.Insert(&obj)
} else {
err2 := col.Update(bson.M{"key": key}, bson.M{"$push": bson.M{"chatinfo": info}})
if err2 != nil && err2 != mgo.ErrNotFound {
panic(err2)
}
}
}
func ReadChatLog(logId int64) { //修改子集列表ChatInfo下的某一条数据的其中IsRead字段
mongo, err := mgo.Dial("mongodb://root:MongoDB@127.0.0.1:27017") // 建立连接
defer mongo.Close()
if err != nil {
panic(err)
}
col := mongo.DB(DB_NAME).C(TABLE_NAME) //选择数据库和集合
err1 := col.Update(bson.M{"chatinfo.logid": logId}, bson.M{"$set": bson.M{"chatinfo.$.isread": true}}) //未读消息
if err1 != nil {
panic(err1)
}
}
func GetUnReadChatLog(pid int64) []*PersonalChatLog { //查找该id的所有未读私聊信息
mongo, err := mgo.Dial("mongodb://root:MongoDB@127.0.0.1:27017") // 建立连接
defer mongo.Close()
if err != nil {
panic(err)
}
col := mongo.DB(DB_NAME).C(TABLE_NAME)
var chatlst []*PersonalChatLog
value := strconv.Itoa(int(pid))
queryBson := bson.M{"key": bson.M{"$regex": value}, "chatinfo.targetid": pid, "chatinfo.isread": false}
m := []bson.M{ //这里的顺序不能乱 必须这样
bson.M{"$unwind": "$chatinfo"},
bson.M{"$match": queryBson},
bson.M{"$project": bson.M{"chatinfo": 1, "_id": 0}},
}
query := col.Pipe(m)
var list []interface{}
err1 := query.All(&list)
if err1 != nil {
panic(err1)
}
for _, n := range list { //因为找出来的数据都是bson.M格式的,要通过json转PersonalChatLog格式
var chat *PersonalChatLog
info := n.(bson.M)
m1 := info["chatinfo"]
j, _ := json.Marshal(m1)
json.Unmarshal(j, &chat)
chatlst = append(chatlst, chat)
}
return chatlst
}
func main() {
//数据结构为一个表多个PersonalChatLogMsg数据格式,key为两个玩家id从小到大组成的字符串 ChatInfo为聊天记录的列表
// type PersonalChatLogMsg struct {
// Key string
// ChatInfo []*PersonalChatLog
//}
talkId := int64(188888888)
targetId := int64(199999999)
info := &PersonalChatLog{
LogId: 1,
Talker: talkId,
TargetId: targetId,
Content: "hello world",
IsRead: false,
}
AddChatLog(info) //增加聊天记录
ReadChatLog(1) //阅读聊天记录
chatList := GetUnReadChatLog(targetId) //查找该id的所有未读私聊信息
if len(chatList) != 0 {
for _, chat := range chatList {
fmt.Println("chatList", chat.LogId)
}
}
info.LogId = 2
AddChatLog(info) //增加聊天记录
chatList1 := GetUnReadChatLog(targetId) //查找该id的所有未读私聊信息
if len(chatList1) != 0 {
for _, chat := range chatList1 {
fmt.Println("chatList1", chat.LogId)
}
}
// 后续添加聊天记录的时候报了一个bug, Resulting document after update is larger than 16777216;
// 查了相关文档才知道原来mongodb数据库单个数据大小不能超过16MB,这里因为ChatInfo列表数据太大超过了16MB.
// 所以这种格式的存储是有问题的,没想到更好的方法,只能修改一个表一个ChatInfo列表格式,这样每个聊天记录的大小不会超过16MB.
// 只不过这样每两个玩家聊天就会有一个聊天表,导致表太多。
}
golang Mongodb 按要求查询子集数据和直接修改子集数据
最新推荐文章于 2024-07-08 22:01:16 发布