存储在 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官方文档:
然后我初步判断是深度问题,因为报文中嵌套还挺多的,但是大小就几百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