Navicat连接MongoDB字段显示Bug,MongoDB 存储限制,GirdFS

问题背景:

存储在 MongoDB 中的一个集合的一个字段的值在 Navicat 16 上看发现值存的不全,这个字段存的是报文,返回的内容会比较长。

所以我觉得是不是有什么配置、默认值之类的,有存储上限。

我也不会 mongo,之前一点都没接触过,所以就网上查各种资料。

先说结论:

Navicat16 有BUG!!!!!!!!!!!,别的版本不知道,但至少16版本绝对有BUG!

是在Navicat上的显示问题!!!

可以用官方的 MongoDB Compass、NoSQLBooster for MongoDB等工具。

验证:

如果在代码里写一个接口查询mongo的数据,会发现,这个字段存储的其实是全的。

这块代码自己随便搜搜吧,没几行代码就不贴了,就是整合springboot根据id查一下mongo记录。

但是我最开始不知道是这个问题,所以就想怎么去解决。

以下均是看了各种资料之后的个人理解,可能有不准确的地方,欢迎多多指正!

因为查资料发现mongo对单个文档有最大限制。如果用navicat看的话,就是每一行就是一个文档,限制最多16M的存储空间,而且还不能调整,如果16M满足不了存储需求,可以用子文档的形式,就是某一列占用空间很大的列上存一个子文档id.

还有个限制就是单个文档深度不能超过100层,一个数组或一个结构体都会加一层。

1、单个文档上限16M.

2、单个文档深度不能超过100层。

MongoDB官方文档:MongoDB Limits and Thresholds — MongoDB Manual
在这里插入图片描述

然后我初步判断是深度问题,因为报文中嵌套还挺多的,但是大小就几百k,远远到不了16M.

最后根据我判断的深度问题自己归纳的三种解决方式:

1、升级mongo到4.4版本以后,从MongoDB 4.4版本开始,MongoDB引入了--maxDepth选项,允许自定义递归深度限制。mongod --maxDepth 200

2、文档中存一个子文档id.

3、使用mongo的GirdFS.


1、这种方式我没试,因为感觉要换版本,开发、测试、生产每个服务器都要换,比较麻烦,而且还不确定能不能解决问题。

2、这种方式好像不行,因为我其实还是要存到文档里超过100层的数据。

3、最终选择了使用mongo的GirdFS.

代码。

maven.

       <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>3.0.9.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
            <version>2.3.12.RELEASE</version>
        </dependency>

保存文件到GirdFS和读取。

import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;

public class MongoController {
    @Autowired
    GridFsTemplate gridFsTemplate;

    @Autowired
    MongoDatabaseFactory mongodbfactory;

    @GetMapping("/save")
    public void save(String filepath) throws FileNotFoundException {
        File file = new File(filepath);
        ObjectId objectId = gridFsTemplate.store(new FileInputStream(file), file.getName(), StandardCharsets.UTF_8);
        System.out.println(objectId);
    }

    @GetMapping("/getFile")
    public void getFile(String id, HttpServletResponse response) throws IOException {
        Query queryById = Query.query(Criteria.where("_id").is(id));
        GridFSFile gridFSFile = gridFsTemplate.findOne(queryById);
        if (gridFSFile != null) {
            MongoDatabase db = mongodbfactory.getMongoDatabase();
            GridFSBucket gridFSBucket = GridFSBuckets.create(db);
            GridFSDownloadStream gridFSDownloadStream =
                    gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
            GridFsResource gridFsResource = new GridFsResource(gridFSFile, gridFSDownloadStream);
            InputStream inputStream = gridFsResource.getInputStream();
            ByteArrayOutputStream byteArrayoutputStream = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int i = 0;
            while (-1 != (i = inputStream.read(bytes))) {
                byteArrayoutputStream.write(bytes, 0, i);
            }
            byte[] byteArray = byteArrayoutputStream.toByteArray();
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(byteArray);
        }
    }


}

MongoDB Compass
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值