MongoDB 查询 命令及 MongoTemplate

命令

1. 查询所有记录:

db.user.find()
相当于:select * from user;

2. 查询 age = 20 的记录:

db.user.find({age:20})
相当于:select * from user where age = 20;

3. 查询 age > 20 的记录:

db.user.find({age:{$gt:20}})
相当于:select * from user where age > 20;

4. 查询 age < 20 的记录:

db.user.find({age:{$lt:20}})
相当于:select * from user where age < 20;

5. 查询 age >= 20 的记录:

db.user.find({age:{$gte:20}})
相当于:select * from user where age >= 20;

6. 查询 age <= 20 的记录:

db.user.find({age:{$lte:20}})
相当于:select * from user where age <= 20;

7. 查询 age >= 20 并且  age <= 30 的记录:

db.user.find({age:{$gte:20,$lte:30}})

8. 查询 name 中包含 '张' 的数据: (模糊查询):

db.user.find({name:/张/})
相当于:select * from user where name like ‘%mongo%’;

9. 查询 name 中 以 '张' 开头的数据:

db.user.find({name:/^张/})
相当于:select * from user where name like ‘mongo%’;

10.查询 name 中 以 '张'结尾的数据:

db.user.find({name:/张$/})
相当于:select * from user where name like ‘%mongo’;

11.查询指定列数据:

db.user.find({},{name:1})  // 查询 name 列数据 第一个字段为查询条件
相当于:select name from user;

注:name 也可用 true 或 false 来表示,为 true 时,与 name:1 效果一样,false 则表示排除 name ,显示 name 以外的列信息

 12.查询指定列,name,age数据,且 age  > 20

db.user.find({age:{$gt:20}},{name:true,age:true})
相当于:select name,age from user where age > 20;

13. 升序、降序排列:

升序:
db.user.find().sort({age:1}) // 以 age 为标准
降序:
db.user.find().sort({age:-1}) 

14. 查询前5条数据:

db.user.find().limit(5)
相当于:selecttop 5 * from user;

15. 查询后10条数据:

db.user.find().skip(10)
相当于:selecttop * from user where id not in(selecttop 10 * from user);

16.查询 5-10之间的数据:

db.user.find().limit(10).skip(5)   // 10 之前,5之后,即 5-10 之间
// 可用于分页,limit 是 pageSize,skip 是第几页 * pageSize

 17.查询 age = 28,或者 age = 29 的数据:

db.user.find({$or:[{age:28},{age:29}]})
相当于:select * from user where age = 28 or age = 29;

18.查询第一条数据:

db.user.findOne()

19.统计查询到的数据的数量:

db.user.find().count()

20.统计 age > 20 的数据的数量:

db.user.find({age:{$gt:20}}).count()

MongoTemplate

1. 根据字段进行查询

最常见的查询场景,比如我们根据查询user=一灰灰blog的数据,这里主要会使用Query + Criteria 来完成

@Component
public class MongoReadWrapper {
    private static final String COLLECTION_NAME = "demo";

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 指定field查询
     */
    public void specialFieldQuery() {
        Query query = new Query(Criteria.where("user").is("一灰灰blog"));
        // 查询一条满足条件的数据
        Map result = mongoTemplate.findOne(query, Map.class, COLLECTION_NAME);
        System.out.println("query: " + query + " | specialFieldQueryOne: " + result);

        // 满足所有条件的数据
        List<Map> ans = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
        System.out.println("query: " + query + " | specialFieldQueryAll: " + ans);
    }
}

上面是一个实际的case,从中可以知道一般的查询方式为:

  • Criteria.where(xxx).is(xxx)来指定具体的查询条件
  • 封装Query对象 new Query(criteria)
  • 借助mongoTemplate执行查询 mongoTemplate.findOne(query, resultType, collectionName)

其中findOne表示只获取一条满足条件的数据;find则会将所有满足条件的返回;上面执行之后,删除结果如

query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { } | specialFieldQueryOne: {_id=5c2368b258f984a4fda63cee, user=一灰灰blog, desc=帅气逼人的码农界老秀}
query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { } | specialFieldQueryAll: [{_id=5c2368b258f984a4fda63cee, user=一灰灰blog, desc=帅气逼人的码农界老秀}, {_id=5c3afaf4e3ac8e8d2d39238a, user=一灰灰blog, desc=帅气逼人的码农界老秀3}, {_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=20.0}, {_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帅气逼人的码农界老秀6, sign=hello world}]

2. and多条件查询

前面是只有一个条件满足,现在如果是要求同时满足多个条件,则利用org.springframework.data.mongodb.core.query.Criteria#and来斜街多个查询条件

/**
 * 多个查询条件同时满足
 */
public void andQuery() {
    Query query = new Query(Criteria.where("user").is("一灰灰blog").and("age").is(18));
    Map result = mongoTemplate.findOne(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | andQuery: " + result);
}

删除结果如下

query: Query: { "user" : "一灰灰blog", "age" : 18 }, Fields: { }, Sort: { } | andQuery: {_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}

3. or或查询

and对应的就是or,多个条件中只要一个满足即可,这个与and的使用有些区别, 借助org.springframework.data.mongodb.core.query.Criteria#orOperator来实现,传参为多个Criteria对象,其中每一个表示一种查询条件

/**
 * 或查询
 */
public void orQuery() {
    // 等同于 db.getCollection('demo').find({"user": "一灰灰blog", $or: [{ "age": 18}, { "sign": {$exists: true}}]})
    Query query = new Query(Criteria.where("user").is("一灰灰blog")
            .orOperator(Criteria.where("age").is(18), Criteria.where("sign").exists(true)));
    List<Map> result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | orQuery: " + result);

    // 单独的or查询
    // 等同于Query: { "$or" : [{ "age" : 18 }, { "sign" : { "$exists" : true } }] }, Fields: { }, Sort: { }
    query = new Query(new Criteria().orOperator(Criteria.where("age").is(18), Criteria.where("sign").exists(true)));
    result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | orQuery: " + result);
}

执行后输出结果为

query: Query: { "user" : "一灰灰blog", "$or" : [{ "age" : 18 }, { "sign" : { "$exists" : true } }] }, Fields: { }, Sort: { } | orQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}, {_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帅气逼人的码农界老秀6, sign=hello world}]
query: Query: { "$or" : [{ "age" : 18 }, { "sign" : { "$exists" : true } }] }, Fields: { }, Sort: { } | orQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}, {_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帅气逼人的码农界老秀6, sign=hello world}, {_id=5c3b0538e3ac8e8d2d392390, user=二灰灰blog, desc=帅气逼人的码农界老秀6, sign=hello world}]

4. in查询

标准的in查询case

/**
 * in查询
 */
public void inQuery() {
    // 相当于:
    Query query = new Query(Criteria.where("age").in(Arrays.asList(18, 20, 30)));
    List<Map> result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | inQuery: " + result);
}

输出

query: Query: { "age" : { "$in" : [18, 20, 30] } }, Fields: { }, Sort: { } | inQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=20.0}]

5. 数值比较

数值的比较大小,主要使用的是 getgtltlet

/**
 * 数字类型,比较查询 >
 */
public void compareBigQuery() {
    // age > 18
    Query query = new Query(Criteria.where("age").gt(18));
    List<Map> result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | compareBigQuery: " + result);

    // age >= 18
    query = new Query(Criteria.where("age").gte(18));
    result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | compareBigQuery: " + result);
}

/**
 * 数字类型,比较查询 <
 */
public void compareSmallQuery() {
    // age < 20
    Query query = new Query(Criteria.where("age").lt(20));
    List<Map> result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | compareSmallQuery: " + result);

    // age <= 20
    query = new Query(Criteria.where("age").lte(20));
    result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | compareSmallQuery: " + result);
}

输出

query: Query: { "age" : { "$gt" : 18 } }, Fields: { }, Sort: { } | compareBigQuery: [{_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=20.0}]
query: Query: { "age" : { "$gte" : 18 } }, Fields: { }, Sort: { } | compareBigQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=20.0}]
query: Query: { "age" : { "$lt" : 20 } }, Fields: { }, Sort: { } | compareSmallQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}]
query: Query: { "age" : { "$lte" : 20 } }, Fields: { }, Sort: { } | compareSmallQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=20.0}]

6. 正则查询

牛逼高大上的功能

/**
 * 正则查询
 */
public void regexQuery() {
    Query query = new Query(Criteria.where("user").regex("^一灰灰blog"));
    List<Map> result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | regexQuery: " + result);
}

输出

query: Query: { "user" : { "$regex" : "^一灰灰blog", "$options" : "" } }, Fields: { }, Sort: { } | regexQuery: [{_id=5c2368b258f984a4fda63cee, user=一灰灰blog, desc=帅气逼人的码农界老秀}, {_id=5c3afacde3ac8e8d2d392389, user=一灰灰blog2, desc=帅气逼人的码农界老秀2}, {_id=5c3afaf4e3ac8e8d2d39238a, user=一灰灰blog, desc=帅气逼人的码农界老秀3}, {_id=5c3afafbe3ac8e8d2d39238b, user=一灰灰blog4, desc=帅气逼人的码农界老秀4}, {_id=5c3afb0ae3ac8e8d2d39238c, user=一灰灰blog5, desc=帅气逼人的码农界老秀5}, {_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=20.0}, {_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帅气逼人的码农界老秀6, sign=hello world}]

7. 查询总数

统计常用,这个主要利用的是mongoTemplate.count方法

/**
 * 查询总数
 */
public void countQuery() {
    Query query = new Query(Criteria.where("user").is("一灰灰blog"));
    long cnt = mongoTemplate.count(query, COLLECTION_NAME);
    System.out.println("query: " + query + " | cnt " + cnt);
}

输出

query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { } | cnt 5

8. 分组查询

这个对应的是mysql中的group查询,但是在mongodb中,更多的是通过聚合查询,可以完成很多类似的操作,下面借助聚合,来看一下分组计算总数怎么玩

/*
 * 分组查询
 */
public void groupQuery() {
    // 根据用户名进行分组统计,每个用户名对应的数量
    // aggregate([ { "$group" : { "_id" : "user" , "userCount" : { "$sum" : 1}}}] )
    Aggregation aggregation = Aggregation.newAggregation(Aggregation.group("user").count().as("userCount"));
    AggregationResults<Map> ans = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);
    System.out.println("query: " + aggregation + " | groupQuery " + ans.getMappedResults());
}

注意下,这里用Aggregation而不是前面的QueryCriteria,输出如下

query: { "aggregate" : "__collection__", "pipeline" : [{ "$group" : { "_id" : "$user", "userCount" : { "$sum" : 1 } } }] } | groupQuery [{_id=一灰灰blog, userCount=5}, {_id=一灰灰blog2, userCount=1}, {_id=一灰灰blog4, userCount=1}, {_id=二灰灰blog, userCount=1}, {_id=一灰灰blog5, userCount=1}]

9. 排序

sort,比较常见的了,在mongodb中有个有意思的地方在于某个字段,document中并不一定存在,这是会怎样呢?

/**
 * 排序查询
 */
public void sortQuery() {
    // sort查询条件,需要用with来衔接
    Query query = Query.query(Criteria.where("user").is("一灰灰blog")).with(Sort.by("age"));
    List<Map> result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | sortQuery " + result);
}

输出结果如下,对于没有这个字段的document也被查出来了

query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { "age" : 1 } | sortQuery [{_id=5c2368b258f984a4fda63cee, user=一灰灰blog, desc=帅气逼人的码农界老秀}, {_id=5c3afaf4e3ac8e8d2d39238a, user=一灰灰blog, desc=帅气逼人的码农界老秀3}, {_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帅气逼人的码农界老秀6, sign=hello world}, {_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=20.0}]

10. 分页

数据量多的时候,分页查询比较常见,用得多就是limit和skip了

/**
 * 分页查询
 */
public void pageQuery() {
    // limit限定查询2条
    Query query = Query.query(Criteria.where("user").is("一灰灰blog")).with(Sort.by("age")).limit(2);
    List<Map> result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | limitPageQuery " + result);


    // skip()方法来跳过指定数量的数据
    query = Query.query(Criteria.where("user").is("一灰灰blog")).with(Sort.by("age")).skip(2);
    result = mongoTemplate.find(query, Map.class, COLLECTION_NAME);
    System.out.println("query: " + query + " | skipPageQuery " + result);
}

输出结果表明,limit用来限制查询多少条数据,skip则表示跳过前面多少条数据

query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { "age" : 1 } | limitPageQuery [{_id=5c2368b258f984a4fda63cee, user=一灰灰blog, desc=帅气逼人的码农界老秀}, {_id=5c3afaf4e3ac8e8d2d39238a, user=一灰灰blog, desc=帅气逼人的码农界老秀3}]
query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { "age" : 1 } | skipPageQuery [{_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帅气逼人的码农界老秀6, sign=hello world}, {_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帅气逼人的码农界老秀6, age=20.0}]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.了解Spring 2.了解NoSQL和文档数据库 3.要求 4.其他帮助资源 4.1。支持 4.1.1。社区论坛 4.1.2。专业支持 4.2。发展之后 5.新&值得注意的 5.1。Spring Data MongoDB 2.1中的新特性 5.2。Spring Data MongoDB 2.0中的新特性 5.3。Spring Data MongoDB 1.10中的新特性 5.4。Spring Data MongoDB 1.9中的新特性 5.5。Spring Data MongoDB 1.8中的新特性 5.6。Spring Data MongoDB 1.7中有什么新功能 6.依赖 6.1。Spring Boot的依赖管理 6.2。Spring框架 7.使用Spring Data Repositories 7.1。核心概念 7.2。查询方法 7.3。定义存储库接口 7.3.1。微调储存库定义 7.3.2。空处理存储库方法 7.3.3。将存储库与多个Spring Data模块一起使用 7.4。定义查询方法 7.4.1。查询查询策略 7.4.2。查询创建 7.4.3。属性表达式 7.4.4。特殊参数处理 7.4.5。限制查询结果 7.4.6。流式查询结果 7.4.7。异步查询结果 7.5。创建存储库实例 7.5.1。XML配置 7.5.2。JavaConfig 7.5.3。独立使用 7.6。Spring Data存储库的自定义实现 7.6.1。定制个人存储库 7.6.2。自定义基础存储库 7.7。从聚合根发布事件 7.8。Spring数据扩展 7.8.1。Querydsl扩展 7.8.2。Web支持 7.8.3。存储库填充程序 7.8.4。传统网络支持 参考文档 8.介绍 8.1。文档结构 9. MongoDB支持 9.1。入门 9.2。示例存储库 9.3。用Spring连接到MongoDB 9.3.1。使用基于Java的元数据注册Mongo实例 9.3.2。使用基于XML的元数据注册Mongo实例 9.3.3。MongoDbFactory接口 9.3.4。使用基于Java的元数据注册MongoDbFactory实例 9.3.5。使用基于XML的元数据注册MongoDbFactory实例 9.4。MongoTemplate简介 9.4.1。实例化MongoTemplate 9.4.2。WriteResultChecking策略 9.4.3。WriteConcern 9.4.4。WriteConcernResolver 9.5。保存,更新和删除文档 9.5.1。如何_id在映射图层中处理该字段 9.5.2。类型映射 9.5.3。保存和插入文件的方法 9.5.4。更新集合中的文档 9.5.5。在集合中插入文档 9.5.6。在集合中查找和插入文档 9.5.7。删除文件的方法 9.5.8。乐观锁定 9.6。查询文件 9.6.1。查询集合中的文档 9.6.2。查询文件的方法 9.6.3。查询不同的值 9.6.4。地理空间查询 9.6.5。GeoJSON支持 9.6.6。全文查询 9.6.7。排序规则 9.6.8。JSON模式 9.6.9。流利的模板API 9.7。按实例查询 9.7.1。介绍 9.7.2。用法 9.7.3。示例匹配器 9.7.4。执行一个例子 9.7.5。无类型示例 9.8。减少地图操作 9.8.1。使用示例 9.9。脚本操作 9.9.1。使用示例 9.10。集团运营 9.10.1。使用示例 9.11。聚合框架支持 9.11.1。基本概念 9.11.2。支持的聚合操作 9.11.3。投影表达式 9.11.4。分面分类 9.12。用自定义转换器覆盖默认映射 9.12.1。使用已注册的Spring Converter进行保存 9.12.2。使用Spring转换器读取 9.12.3。使用MongoConverter注册Spring转换器 9.12.4。转换器消除歧义 9.13。索引和集合管理 9.13.1。创建索引的方法 9.13.2。访问索引信息 9.13.3。使用集合的方法 9.14。执行命令 9.14.1。执行命令的方法 9.15。生命周期事件 9.16。例外翻译 9.17。执行回调 9.18。GridFS支持 9.19。更改流 9.19.1。使用MessageListener更改流 9.19.2。更改流 - 无效 10.反应性的MongoDB支持 10.1。入门 10.2。使用Spring和Reactive Streams Driver连接到MongoDB 10.2.1。使用基于Java的元数据注册MongoClient实例 10.2.2。ReactiveMongoDatabaseFactory接口 10.2.3。使用基于

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值