使用MongoDB存储集合的一些问题

这两天在工作中被Mongo集合存储给整得头大,当然也是我的认知太浅,所以下面我来分享下我所遇到的这个问题希望有大佬能给出更好的解决方案,

1.需求:

  存储一个从前端接收未知数据类型的集合

     例:

           由于是未知的数据类型,所有我创建了一个IList<Object>集合

public class Demo
{
        public String Name { get; set; }
        public List<Object> List { get; set; }
}

2.问题

  按照我们平常的想法我们只要将数据从api接收到并且进行存储即可,那么事实真是如此吗,下面我们来进行一个简单的测试

  首先创建api

[RoutePrefix("Home")]
    public class HomeController : ApiController
    {
        public HomeController() { }
        //连接地址
        private static string conn = "mongodb://192.168.11.51:40000";
        //数据库名称
        private static string dbName = "yan";
        //集合名称
        private static string colName = "Demo";
        static MongoClient client = new MongoClient(conn);
        //获取指定数据库
        static IMongoDatabase db = client.GetDatabase(dbName);
        //获取指定集合   BsonDocument数据库文档对象
        static IMongoCollection<Demo> coll = db.GetCollection<Demo>(colName);
        [HttpPost]
        [Route("TestMongo")]
        public void TestMongo([FromBody] Demo demo)
        {
            coll.InsertOne(demo);
        }
    }

    从上面可以看出我们在TestMongo只做了一件事,就是讲接收到的数据进行存储,

    然后我们使用PostMan进行模拟请求测试

   可以看到后台如愿的获取到了请求数据,那么存储到Mongo中是什么呢,我们来看一下

 

     可以看到这个集合存储到Mongo中变成了一组我们几乎看不懂的数据结构,那么这到底是怎么回事,下面我解析下我猜想的跟其解决方法。

  3.解决方案

    首先我们来获取解析下从客户端接收到的集合类型

    我们可以看到集合中存储的每一个类型是JObject类型,而展开这个类型时发现里面数据结构好像根本无法解析所以导致我们在存储时并没有按照我们所想的那样进行存储,那么该怎么进行解决呢,整了两天整出了一个不算好的解决方案,

     首先将集合改成IEnumberable<Object>类型(后面解释其原因)

public class Demo
{
        public String Name { get; set; }
        public IEnumerable<Object> List { get; set; }
}

    然后在api中做一些特殊处理

 public void TestMongo([FromBody] Demo demo)
{
            //1.将集合包装成一个Object集合序列化
            String strVal = JsonConvert.SerializeObject(new { data = demo.List });
            //2.将序列化的字符串转换成BsonDocument类型
            BsonDocument doc = BsonDocument.Parse(strVal);
            //3.使用BsonDocument获取被包装的集合并转换成BsonArray类型
            var docArr = doc.GetValue("data").AsBsonArray;
            //4.获取BsonArray的Values值并重写赋给原集合引用
            //【因为Values值是IEnumerable<BsonValue>类型,所以原集合必须是IEnumerable<Object>类型】
            demo.List = doc.Values;


            coll.InsertOne(demo);
}

 

  上面代码我们就可以将集合按照我们所想那样进行存储,我们来看一下效果

    上面方案我感觉并不好,但是并没有找到更好的方法,在此希望各位大佬能给出更好的解决方案

 

### 回答1: 你可以使用 MongoDB 的 Go 语言驱动来连接 MongoDB 数据库,然后使用 `Collection.Find` 方法来执行查询。 这是一个示例代码: ``` package main import ( "context" "fmt" "log" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { // 创建 MongoDB 连接 client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017")) if err != nil { log.Fatal(err) } err = client.Connect(context.TODO()) if err != nil { log.Fatal(err) } // 获取要操作的集合 collection := client.Database("test").Collection("mycoll") // 构建查询过滤器 filter := bson.M{"name": "foo"} // 执行查询 cur, err := collection.Find(context.TODO(), filter) if err != nil { log.Fatal(err) } defer cur.Close(context.TODO()) // 遍历查询结果 for cur.Next(context.TODO()) { var result bson.M err := cur.Decode(&result) if err != nil { log.Fatal(err) } fmt.Println(result) } if err := cur.Err(); err != nil { log.Fatal(err) } } ``` 这段代码会连接到本地的 MongoDB 服务器,然后在 `test` 数据库的 `mycoll` 集合中查找所有名字为 `foo` 的文档。 需要注意,这个示例代码使用MongoDB Go 驱动的最新版本,使用了一些新的特性,如 `context.TODO` 和 `options.Client().ApplyURI`。 如果你使用的是旧版本的驱动,你可能需要使用不同的写法。 ### 回答2: 使用golang操作mongodb可以通过使用官方提供的mongo-go-driver包来完成。以下是使用golang查询指定集合信息的步骤: 1.安装mongo-go-driver包:使用go mod命令进行包的安装,命令如下: ```bash go get go.mongodb.org/mongo-driver ``` 2.导入所需的包:在golang代码的文件中,导入mongo-go-driver操作mongodb的相关包,例如: ```go import ( "context" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) ``` 3.建立mongodb连接:使用mongo.Connect函数建立到mongodb服务器的连接,例如: ```go clientOptions := options.Client().ApplyURI("mongodb://localhost:27017") client, err := mongo.Connect(context.Background(), clientOptions) ``` 4.选择数据库集合使用client.Database函数选择要查询的数据库,然后使用Database.Collection函数选择要查询的集合,例如: ```go database := client.Database("mydb") collection := database.Collection("mycollection") ``` 5.执行查询操作:使用Find函数进行查询操作,并使用cursor.All函数获取查询结果,例如: ```go cursor, err := collection.Find(context.Background(), bson.M{"name": "John"}) if err != nil { // 处理错误 } defer cursor.Close(context.Background()) var documents []bson.M if err = cursor.All(context.Background(), &documents); err != nil { // 处理错误 } ``` 6.处理查询结果:根据需要进行相应的处理,例如遍历documents数组,打印查询的结果,例如: ```go for _, document := range documents { fmt.Println(document) } ``` 以上是使用golang查询指定集合信息的基本步骤。通过mongo-go-driver包提供的函数和方法,可以灵活地查询和操作mongodb数据库中的数据。 ### 回答3: 使用golang查询指定集合的信息,需要先安装golang的mongodb驱动程序。可以使用以下命令安装: ``` go get go.mongodb.org/mongo-driver/mongo ``` 安装完成后,可以开始编写golang代码以查询指定集合的信息。以下是一个示例代码: ```go package main import ( "context" "fmt" "log" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type Person struct { Name string Age int Email string } func main() { // 设置MongoDB连接选项 clientOptions := options.Client().ApplyURI("mongodb://localhost:27017") // 连接到MongoDB client, err := mongo.Connect(context.TODO(), clientOptions) if err != nil { log.Fatal(err) } // 检查连接 err = client.Ping(context.TODO(), nil) if err != nil { log.Fatal(err) } fmt.Println("Connected to MongoDB!") // 获取指定集合的句柄 collection := client.Database("mydatabase").Collection("people") // 创建一个用于存储结果的slice var results []Person // 查询集合中的所有文档 cur, err := collection.Find(context.TODO(), bson.D{}) if err != nil { log.Fatal(err) } // 遍历查询结果 for cur.Next(context.TODO()) { // 创建一个临时变量用于存储单个文档 var elem Person err := cur.Decode(&elem) if err != nil { log.Fatal(err) } // 将文档添加到结果slice中 results = append(results, elem) } // 如果在遍历过程中发生错误,则记录该错误 if err := cur.Err(); err != nil { log.Fatal(err) } // 关闭游标 cur.Close(context.TODO()) fmt.Printf("Found %v documents\n", len(results)) } ``` 在上面的代码中,首先定义了一个结构体`Person`,代表集合中的每个文档。然后使用MongoDB驱动程序提供的函数连接到MongoDB,并获取到指定集合的句柄。接下来,使用`collection.Find()`函数查询指定集合中的所有文档,并将结果存储到一个slice中。最后,遍历查询结果,并将每个文档添加到结果slice中。输出最终结果时,使用`len(results)`获取结果的数量。 需要注意的是,上述代码只是一个示例,实际使用时,可能需要根据自己的需求来修改代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值