文章目录
查询collection中指定属性
1.直接通过Query查询
Query query=new Query();
Criteria criteria=new Criteria();
criteria.and("accountId").is(accountId);
query.addCriteria(criteria);
query.fields().include("templateId").include("templateName").include("templateDesc");//查询指定属性
List<FormTemplate> formTemplates = mongoTemplate.find(query, FormTemplate.class);
转义成查询json
{ "accountId" : { "$numberLong" : "2" } } fields: Document{{templateName=1, templateDesc=1, _id=1}}
2.使用aggregate(集合)算子进行两阶段管道操作
TypedAggregation<Dog> countAggr = Aggregation.newAggregation(Dog.class,
Aggregation.match(criteria), Aggregation.project("filed1","filed2"));//选择指定属性
AggregationResults<Dog> aggregate = mongoTemplate.aggregate(countAggr, Dog.class);
List<Dog> mappedResults = aggregate.getMappedResults();
对document进行"存在则更新不存在则新增"操作
mongoDB在进行数据持久化时,采用离散存储方式。即删除的document占用的存储空间并不会被回收。所以尽量不要对mongoDB进行频繁删除新增操作。对于数据库操作中“存在则更新不存在则新增”的业务场景。可采用upsert方式执行。
Query query=new Query(where("_id").is(formTemplate.getTemplateId()));
Update update=new Update();
update.set("controlList",formTemplate.getControlList());
update.set("createId",formTemplate.getCreateId());
update.set("createTime",formTemplate.getCreateTime());
update.set("updateId",formTemplate.getUpdateId());
update.set("updateTime",formTemplate.getUpdateTime());
update.set("accountId",formTemplate.getAccountId());
UpdateResult upsertResult = mongoTemplate.upsert(query, update);
boolean res = upsertResult.wasAcknowledged();
MongoCursor使用
mongoDB每次从数据库加载数据时默认仅使用16MB的缓存空间,如果需要读取大量的数据,例如读取上百万的document到内存中,超过16MB的缓存大小会报错。为了解决如上问题,mongo提供了游标的方式分段的去加载。参见mongo官方文档关于Cursor的介绍。
对常见的 db.collection.find()操作,返回的就是一个cursor,一个cursor返回的记录条数可以通过DBQuery.shellBatchSize=50命令进行设置,也可以通过DBQuery.shellBatchSize命令进行查看。mongodb-driver提供了对Cursor的封装——MongoCursor。而Spring data mongoDB本质是基于mongodb-driver的,所以可以采用MongoCursor分阶段的将大容量数据加载到内存中。
示例代码:
Query query=new Query();
query.addCriteria(criteria);
//batchSize设置一次性加载的记录条数,noCursorTimeout设置游标的过期时间为永远不过期,直到加载完所有记录为止,对于大数据量的加载需要设置此属性,如果不设置,mongoDB会默认在10分钟后关闭此cursor
MongoCursor<Document> iterator = mongoTemplate.getCollection("osgidevices").find().batchSize(100)
.noCursorTimeout(true).iterator();
List<OsigiDevices> all = new ArrayList<OsigiDevices>();
int i=0;
while (iterator.hasNext()){
Document document = iterator.next();
//使用mongoConverter将Document转换成对应java实体类
all.add(mongoConverter.read(OsigiDevices.class,document));
i++;
if(i%10000==0){
System.out.println("已导入"+i+"条数据");
}
}
注意MongoCursor如果遍历完所有记录会自动关闭,如果仅仅是遍历了一条记录需要显式关闭MongoCursor。例如:
...
Document doc1 = mongoCursor.next();//只从iterator中取一条记录
mongoCursor.close();
如果不关闭,相当于一直打开的一个数据库连接,占用内存,虽然会在一定时间后被mongoDB关闭,但是并发量大时仍然会有内存泄漏的风险。
可参考如下文章
https://stackoverflow.com/questions/24260677/mongodb-why-should-we-close-the-cursor-after-it-is-used
基于Document对mongoDB原生js操作命令转义
js是直接与mongoDB交互的官方方式,具体的交互指令是封装了一些函数操作符的json。spring data mongoDB本质是对mongoClient进行封装,使用Document对象描述json。对于spring data mongoDB api不熟悉的同学可以使用mongoClient进行操作。
例如如下原生js集合操作,对osgidevices表中数据匹配lastday等于20190719,countycode存在的字段进行提取,然后按照areacode和countycode两个字段进行分组,并将activecount字段求和。
使用mongoClient+document的方式则是:
Document matchdoc = new Document("$match",
new Document("lastday", date).append("countycode", new Document("$exists", true)));
Document groupdoc = new Document("$group",
new Document("_id",
new Document("areacode", "$areacode").append("countycode", "$countycode")
.append("countyname", "$countyname").append("manufacturer",
"$manufacturer")).append("activecount",
new Document("$sum", 1)));
MongoClient mongoClient=new MongoClient("url information");
MongoCursor<Document> iterator = mongoClient.getDatabase("").getCollection("")
.aggregate(aggregatelist).iterator();
获得一个MongoCursor对象,进行迭代得到结果。
mongoDB根据多属性是否存在查询相关记录
db.getCollection('osgiSpeedResult').find(
{'webTestInfo':{ $exists: true }},
{'osgiDownloadTestInfo':{ $exists: false }},
{'osgiUploadTestInfo':{ $exists: false }});
mongoDB删除根据查询条件筛选的记录
db.getCollection('osgiSpeedResult').deleteMany(
{'webTestInfo':{ $exists: true }},
{'osgiDownloadTestInfo':{ $exists: false }},
{'osgiUploadTestInfo':{ $exists: false }});
mongoDB对查询出的记录根据时间倒叙排序并取前n条记录
db.getCollection('osgiSpeedResult').find(
{'webTestInfo':{ $exists: true }},
{'osgiDownloadTestInfo':null},
{'osgiUploadTestInfo':null}).sort({ time : -1 }).limit(10);
mongoDB根据属性数据类型进行查询
$type操作符
检测类型
种类 代号 别名
Double 1 “double”
String 2 “string”
Object 3 “object”
Array 4 “array”
Binary data 5 “binData”
Undefined 6 “undefined” Deprecated.
ObjectId 7 “objectId”
Boolean 8 “bool”
Date 9 “date”
Null 10 “null”
Regular Expression 11 “regex”
DBPointer 12 “dbPointer”
JavaScript 13 “javascript”
Symbol 14 “symbol”
JavaScript (with scope) 15 “javascriptWithScope”
32-bit integer 16 “int”
Timestamp 17 “timestamp”
64-bit integer 18 “long”
Min key -1 “minKey”
原文链接:https://blog.csdn.net/demon_LL/article/details/60870824
查询指定属性是字符串的类型
db.getCollection('osgiSpeedResult').find(
{'osgiDownloadTestInfo':{ $type : 2 }});
mongoClient连接mongoDB
maven引入mongo driver包
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
</dependency>
连接mongoDB,构建MonogoClient对象,建议可以使用单例模式创建
public static void init(String mongolist, String username, String password) {
MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
builder.readPreference(ReadPreference.secondaryPreferred());
MongoClientURI clientURI = null;
if (StringUtils.isNotBlank(username) || StringUtils.isNotBlank(password)) {
clientURI = new MongoClientURI(
"mongodb://" + username + ":" + password + "@" + mongolist, builder);
} else {
clientURI = new MongoClientURI("mongodb://" + mongolist, builder);
}
client = new MongoClient(clientURI);
}