Spring Data Mongodb的API及案例(exists、gt、in、is、orOperator 、regex、size)
Criteria提供的以下方法,这些方法都对应着MongoDB中的运算符,所有的方法返回值依旧是Criteria类。
1. exists条件的使用
推荐阅读—MongoDB操作符$exists
- 当boolean为true,
$exists
匹配包含字段的文档,包含字段为null的文档。 - 当boolean为false,
$exists
返回不包含字段的文档。
db.testelemMatch3.insert([
{"find": "project1","tags": [{"key": "area", "value": "IT"},{"key": "department", "value": "Architecture"}]},
{"find": "project2","tags": [{"key": "area", "value": "HR"},{"key": "department", "value": "IT"}]}
])
public static void find9() {
Criteria criteria = Criteria.where("key").exists(true);
Query query = Query.query(criteria);
log.info("流程:{}", query);
List<BasicDBObject> basicDBObjects = mongoTemplate.find(query,
BasicDBObject.class, "testelemMatch3");
log.info("最终数据{}", JSON.toJSONString(basicDBObjects));
}
生成的原生语句:
{ "key" : { "$exists" : true} }
因为使用了exists=true
,若文档中不包含key
字段,那么最终返回的数据为[]
。
2. 比较运算符的使用
符号 | 描述 |
---|---|
gt | 大于 |
gte | 大于等于 |
lt | 小于 |
lte | 小于等于 |
案例一:筛选成绩是(90,100)的文档
db.stus.insert([
{ "_id" : ObjectId("5e64bf9a2a16affa306b8b93"), "name" : "数组1", "age" : "18","gender" : "男","scope" : 77.0},
{"_id" : ObjectId("5e64cc2b6ef8da42f1854b11"), "name" : "数组2","age" : "13", "gender" : "女","scope" : 89},
{ "_id" : ObjectId("5e663e7379bbd40eb81de8eb"),"name" : "数组3","age" : "13","gender" : "男","scope" : 60},
{"_id" : ObjectId("5e6648d179bbd40eb81de8ee"),"name" : "数组4","age" : "14","gender" : "男","scope" : 59},
{"_id" : ObjectId("5e6648d479bbd40eb81de8f0"),"name" : "数组5","age" : "18","gender" : "男","scope" : 68},
{"_id" : ObjectId("5e6648d879bbd40eb81de8f1"),"name" : "数组6","age" : "24","gender" : "男","scope" : 56},
{"_id" : ObjectId("5e6648d979bbd40eb81de8f2"),"name" : "数组7","age" : "25","gender" : "女", "scope" : 90},
{ "_id" : ObjectId("5e6648d979bbd40eb81de8f3"),"name" : "数组8","age" : "24","gender" : "男","scope" : 98},
{ "_id" : ObjectId("5e6648d979bbd40eb81de8f4"),"name" : "数组9", "age" : "18","gender" : "男","scope" : 45},
{ "_id" : ObjectId("5e6648d979bbd40eb81de8f5"),"name" : "数组10", "age" : "14", "gender" : "女", "scope" : 67}
]);
public static void find9() {
Criteria criteria = Criteria.where("scope").gt(90).lt(100);
Query query = Query.query(criteria);
log.info("流程:{}", query);
List<BasicDBObject> basicDBObjects = mongoTemplate.find(query,
BasicDBObject.class, "stus");
log.info("最终数据{}", JSON.toJSONString(basicDBObjects));
}
生成的原生语句:
{ "scope" : { "$gt" : 90, "$lt" : 100 } }
生成结果:
[{"_id":{"counter":1960179,"date":1583761625000,"machineIdentifier":7977940,"processIdentifier":3768,"time":1583761625000,"timeSecond":1583761625,"timestamp":1583761625},"name":"数组8","age":"24","gender":"男","scope":98}]
案例二:筛选文档内联数组中元素符合大于80小于90的文档。
db.testelemMatch.insert([
{ "name" :"数组1" , "score" : [70.0 , 80.0 , 100.0]},
{ "name" :"数组2" , "score" : [ 120.0 , 60.0]},
{ "name" :"数组2" , "score" : [ 88.0 , 99.0]},
{ "name" :"数组2" , "score" : [ 18.0 , 59.0]},
{ "name" :"数组2" , "score" : [ 28.0 , 79.0]},
{ "name" :"数组3" , "score" : [ 48.0 , 89.0]}
])
可以看到where
条件填写的是$gt
,并没有使用gt()
方法。注意使用的是elemMatch
操作符,使得至少有一个元素完全符合(80,90)的条件。
Criteria c1 = Criteria.where("$gt").is(80).and("$lt").is(90);
Query query = new Query(Criteria.where("score").elemMatch(c1));
//映射关系,该元素会被映射。
query.fields().include("score");
生成的原生语句。
{ "score" : { "$elemMatch" : { "$gt" : 80, "$lt" : 90 } } }
3. in操作符的使用
in
可参考sql中的in
,即可匹配多个条件。
public static void find9() {
// List<String> data = new ArrayList<>();
// data.add("数组1");
// data.add("数组2");
// Criteria criteria = Criteria.where("name").in(data);
//处理数据
Criteria criteria = Criteria.where("name").in("数组1", "数组2");
Query query = Query.query(criteria);
log.info("流程:{}", query);
List<BasicDBObject> basicDBObjects = mongoTemplate.find(query,
BasicDBObject.class, "testelemMatch");
log.info("最终数据{}", JSON.toJSONString(basicDBObjects));
}
输出的原生语句:
{ "name" : { "$in" : ["数组1", "数组2"] } }
4. is方法
使用字段匹配({key:value})
,is()
中的参数是value
值。
public static void find9() {
Criteria criteria = Criteria.where("name").is("数组1");
Query query = Query.query(criteria);
log.info("流程:{}", query);
List<BasicDBObject> basicDBObjects = mongoTemplate.find(query,
BasicDBObject.class, "testelemMatch");
log.info("最终数据{}", JSON.toJSONString(basicDBObjects));
}
输出的原生语句:
{ "name" : "数组1" }
5. orOperator — 或者
相当于or
的作用。
db.items.insert([
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") },
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") },
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") },
{ "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") },
{ "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") }
]);
案例:筛选item
为abc
或者 price
为20
的文档。
public static void find9() {
//注:Criteria.where("item")方法实际上执行的是return new Criteria(key);
//也可以使用无参的构造方法
Criteria criteria = new Criteria().orOperator(
Criteria.where("item").is("abc"),
Criteria.where("price").is(20)
);
Query query = Query.query(criteria);
log.info("流程:{}", query);
List<BasicDBObject> basicDBObjects = mongoTemplate.find(query,
BasicDBObject.class, "items");
log.info("最终数据{}", JSON.toJSONString(basicDBObjects));
}
输出的原生语句:
{ "$or" : [{ "item" : "abc" }, { "price" : 20 }] }
输出结果:
[{"_id":1,"item":"abc","price":10,"quantity":2,"date":1393660800000},
{"_id":2,"item":"jkl","price":20,"quantity":1,"date":1393664400000},
{"_id":5,"item":"abc","price":10,"quantity":10,"date":1396646593331}]
案例二—Spring整合MongoDB实现多个or的范围查询
6. regex 正则
public static void find9() {
Criteria criteria=new Criteria();
//传入的条件
String keyword="a";
//Pattern.CASE_INSENSITIVE 启用不区分大小写的正则表达。
Pattern pattern = Pattern.compile("^.*" + keyword + ".*$", Pattern.CASE_INSENSITIVE);
criteria.and("item").regex(pattern);
Query query = Query.query(criteria);
log.info("流程:{}", query);
List<BasicDBObject> basicDBObjects = mongoTemplate.find(query,
BasicDBObject.class, "items");
log.info("最终数据{}", JSON.toJSONString(basicDBObjects));
}
输出的原生语句:
{ "item" : { "$regex" : "^.*a.*$", "$options" : "i" }
7. size — 获取指定数组长度的文档
输出数组长度为3的文档。
public static void find9() {
Criteria criteria=new Criteria();
//寻找数组长度3的文档。
criteria.and("score").size(3);
Query query = Query.query(criteria);
log.info("流程:{}", query);
List<BasicDBObject> basicDBObjects = mongoTemplate.find(query,
BasicDBObject.class, "testelemMatch");
log.info("最终数据{}", JSON.toJSONString(basicDBObjects));
}
输出的原生语句:
{ "score" : { "$size" : 3 } }
输出结果:
[{"_id":{"counter":4946571,"date":1583927738000,"machineIdentifier":2016652,"processIdentifier":-15175,"time":1583927738000,"timeSecond":1583927738,"timestamp":1583927738},"name":"数组1","score":[70,80,100]}]
8. 判断mongo属性存在性
db.getCollection('collect0').find({'lat':{'$exists': 'True'}})
利用这个句柄,会得到类似可以for i in cursor的格式,来进行处理。