From eab621e06d8d2d21d9426eb64ad37ae3337927af Mon Sep 17 00:00:00 2001 From: libo Date: Fri, 7 Jun 2024 10:55:26 +0800 Subject: [PATCH 1/4] Use 'seqSuffix' to sort MsgDocModel in GetMsgDocModelByIndex --- pkg/common/storage/database/mgo/msg.go | 44 ++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/pkg/common/storage/database/mgo/msg.go b/pkg/common/storage/database/mgo/msg.go index a7291fcc8f..829561f5ca 100644 --- a/pkg/common/storage/database/mgo/msg.go +++ b/pkg/common/storage/database/mgo/msg.go @@ -204,9 +204,47 @@ func (m *MsgMgo) GetMsgDocModelByIndex(ctx context.Context, conversationID strin if sort != 1 && sort != -1 { return nil, errs.ErrArgs.WrapMsg("mongo sort must be 1 or -1") } - opt := options.Find().SetLimit(1).SetSkip(index).SetSort(bson.M{"doc_id": sort}).SetLimit(1) - filter := bson.M{"doc_id": primitive.Regex{Pattern: fmt.Sprintf("^%s:", conversationID)}} - msgs, err := mongoutil.Find[*model.MsgDocModel](ctx, m.coll, filter, opt) + + // 构建聚合管道 + pipeline := mongo.Pipeline{ + {{ + "$match", bson.D{ + {"doc_id", bson.M{"$regex": fmt.Sprintf("^%s:", conversationID)}}, + }, + }}, + {{ + "$project", bson.M{ + "doc_id": 1, + "seqSuffix": bson.M{ // 创建一个新字段来存储转换后的 seqSuffix 整数 + "$toInt": bson.M{ // $toInt 表达式 + "$arrayElemAt": bson.A{ // $arrayElemAt 需要一个数组作为第一个参数 + bson.M{"$split": []interface{}{"$doc_id", ":"}}, // $split 表达式 + -1, // 索引,取数组的最后一个元素 + }, + }, + }, + "msgs": 1, + }, + }}, + {{ + "$sort", bson.D{ // 按 seqSuffix 排序 + {"seqSuffix", sort}, + }, + }}, + } + + // 如果需要分页,可以在这里添加逻辑来动态地修改 pipeline + if index > 0 { + pipeline = append(pipeline, bson.D{{ + "$skip", index, + }}) + } + pipeline = append(pipeline, bson.D{{ + "$limit", 1, // 我们只需要一个文档 + }}) + + // 执行聚合查询 + msgs, err := mongoutil.Aggregate[*model.MsgDocModel](ctx, m.coll, pipeline) if err != nil { return nil, err } From ce2d97f5f892983f783e4e6c54706aae54c5a1e2 Mon Sep 17 00:00:00 2001 From: libo Date: Fri, 7 Jun 2024 11:10:11 +0800 Subject: [PATCH 2/4] test GetMsgDocModelByIndex --- pkg/common/storage/database/mgo/msg_test.go | 58 +++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 pkg/common/storage/database/mgo/msg_test.go diff --git a/pkg/common/storage/database/mgo/msg_test.go b/pkg/common/storage/database/mgo/msg_test.go new file mode 100644 index 0000000000..9b8467f853 --- /dev/null +++ b/pkg/common/storage/database/mgo/msg_test.go @@ -0,0 +1,58 @@ +package mgo + +import ( + "context" + "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/tools/db/mongoutil" + "testing" +) + +func GetTestDriver(t *testing.T, ctx context.Context) (database.Msg, error) { + + var mongoConf config.Mongo + mongoConf.URI = "" + mongoConf.Address = []string{"192.168.3.212:37017"} + mongoConf.Database = "openIM_v3" + mongoConf.Username = "root" + mongoConf.Password = "openIM123" + mongoConf.MaxPoolSize = 100 + mongoConf.MaxRetry = 10 + + mgocli, err := mongoutil.NewMongoDB(ctx, mongoConf.Build()) + if err != nil { + t.Fatal("NewMongoDB failed: ", err) + return nil, err + } + mongoDB := mgocli.GetDB() + + err = mongoDB.Client().Ping(ctx, nil) + if err != nil { + t.Fatal("Ping failed: ", err) + return nil, err + } + + return NewMsgMongo(mongoDB) +} + +func TestMsgMgo_GetMsgDocModelByIndex(t *testing.T) { + ctx := context.Background() + + driver, _ := GetTestDriver(t, ctx) + + conversationID := "si_10043_10070" + msg, err := driver.GetMsgDocModelByIndex(ctx, conversationID, 0, 1) + if err != nil { + t.Fatal("GetMsgDocModelByIndex failed: ", err) + } + + fmt.Println("GetMsgDocModelByIndex Ascent(1): ", msg.DocID) + + msg2, err := driver.GetMsgDocModelByIndex(ctx, conversationID, 0, -1) + if err != nil { + t.Fatal("GetMsgDocModelByIndex failed: ", err) + } + + fmt.Println("GetMsgDocModelByIndex Descent(-1): ", msg2.DocID) +} From ddda8e950cdf55ba229cee8ecfea11355bb9f6e3 Mon Sep 17 00:00:00 2001 From: libo Date: Wed, 19 Jun 2024 11:40:23 +0800 Subject: [PATCH 3/4] Translate Chinese comments into English. --- pkg/common/storage/database/mgo/msg.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/common/storage/database/mgo/msg.go b/pkg/common/storage/database/mgo/msg.go index 829561f5ca..629713ff31 100644 --- a/pkg/common/storage/database/mgo/msg.go +++ b/pkg/common/storage/database/mgo/msg.go @@ -205,7 +205,7 @@ func (m *MsgMgo) GetMsgDocModelByIndex(ctx context.Context, conversationID strin return nil, errs.ErrArgs.WrapMsg("mongo sort must be 1 or -1") } - // 构建聚合管道 + // parepare pipeline pipeline := mongo.Pipeline{ {{ "$match", bson.D{ @@ -215,11 +215,11 @@ func (m *MsgMgo) GetMsgDocModelByIndex(ctx context.Context, conversationID strin {{ "$project", bson.M{ "doc_id": 1, - "seqSuffix": bson.M{ // 创建一个新字段来存储转换后的 seqSuffix 整数 - "$toInt": bson.M{ // $toInt 表达式 - "$arrayElemAt": bson.A{ // $arrayElemAt 需要一个数组作为第一个参数 - bson.M{"$split": []interface{}{"$doc_id", ":"}}, // $split 表达式 - -1, // 索引,取数组的最后一个元素 + "seqSuffix": bson.M{ // Create a new field to store the converted seqSuffix integer. + "$toInt": bson.M{ // $toInt expression + "$arrayElemAt": bson.A{ // $arrayElemAt requires an array as the first argument. + bson.M{"$split": []interface{}{"$doc_id", ":"}}, // $split expression + -1, // Indexing, to take the last element of the array. }, }, }, @@ -227,23 +227,23 @@ func (m *MsgMgo) GetMsgDocModelByIndex(ctx context.Context, conversationID strin }, }}, {{ - "$sort", bson.D{ // 按 seqSuffix 排序 + "$sort", bson.D{ // Sort by seqSuffix. {"seqSuffix", sort}, }, }}, } - // 如果需要分页,可以在这里添加逻辑来动态地修改 pipeline + // If pagination is needed, logic can be added here to dynamically modify the pipeline. if index > 0 { pipeline = append(pipeline, bson.D{{ "$skip", index, }}) } pipeline = append(pipeline, bson.D{{ - "$limit", 1, // 我们只需要一个文档 + "$limit", 1, // We only need one document. }}) - // 执行聚合查询 + // Execute an aggregation query. msgs, err := mongoutil.Aggregate[*model.MsgDocModel](ctx, m.coll, pipeline) if err != nil { return nil, err From f22c5920ced0705695d670419078c5496b1cc477 Mon Sep 17 00:00:00 2001 From: libo Date: Wed, 19 Jun 2024 11:42:16 +0800 Subject: [PATCH 4/4] Add License --- pkg/common/storage/database/mgo/msg.go | 14 ++++++++++++++ pkg/common/storage/database/mgo/msg_test.go | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/pkg/common/storage/database/mgo/msg.go b/pkg/common/storage/database/mgo/msg.go index 629713ff31..611ed11e61 100644 --- a/pkg/common/storage/database/mgo/msg.go +++ b/pkg/common/storage/database/mgo/msg.go @@ -1,3 +1,17 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package mgo import ( diff --git a/pkg/common/storage/database/mgo/msg_test.go b/pkg/common/storage/database/mgo/msg_test.go index 9b8467f853..65b8f64683 100644 --- a/pkg/common/storage/database/mgo/msg_test.go +++ b/pkg/common/storage/database/mgo/msg_test.go @@ -1,3 +1,17 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package mgo import (