Java查询MongoDB数据库案例大全
作者:记录学习的習習君
写在前面:
实习期间做公司的任务,用的是MongoDB。刚接触感觉很多东西都不会,现在任务做完了。回过头来记录和巩固一下知识,也方面以后回来查阅。本篇博客只记录Mongodb的查询方法,方便查找!MongoDB 4.0以上版本!! 废话不多说,直接开始记录:
1. 查询所有文档
// 获取集合 MongoCollection<User> collection = mongoDatabase.getCollection("users", User.class); // 查询所有文档 List<User> userList = new ArrayList<>(); MongoCursor<User> cursor = collection.find().iterator(); while (cursor.hasNext()) { User user = cursor.next(); userList.add(user); }
在这个示例中,我们首先获取了名为users
的集合,并将其映射到User
类。接着,我们使用find()
方法查询集合中的所有文档,并使用iterator()
方法获取游标对象。通过遍历游标对象中的结果,我们可以将每个文档转换为User
对象,并将其添加到一个List
中。最终,我们可以在userList
中找到所有查询结果。
2. 指定查询条件
指定查询条件可以使用find()
方法的参数。该参数是一个Bson
对象,用于指定查询条件。Bson
是MongoDB提供的一个接口,用于构建查询条件。
// 获取集合 MongoCollection<User> collection = mongoDatabase.getCollection("users", User.class); // 构建查询条件 Bson filter = Filters.eq("name", "John"); // 查询文档 List<User> userList = new ArrayList<>(); MongoCursor<User> cursor = collection.find(filter).iterator(); while (cursor.hasNext()) { User user = cursor.next(); userList.add(user); }
构建查询条件有很多种,以下分类:
等于:
Filters.eq("name", "John")
,用于查询name
属性等于"John"
的文档。
不等于:
Filters.ne("name", "John")
,用于查询name
属性不等于"John"
的文档。
大于:
Filters.gt("age", 18)
,用于查询age
属性大于18
的文档。
大于等于:
Filters.gte("age", 18)
,用于查询age
属性大于等于18
的文档。
小于:
Filters.lt("age", 30)
,用于查询age
属性小于30
的文档。
小于等于:
Filters.lte("age", 30)
,用于查询age
属性小于等于30
的文档。
包含:
Filters.in("name", Arrays.asList("John", "Mike"))
,用于查询name
属性包含在"John"
和"Mike"
中的文档。
不包含:
Filters.nin("name", Arrays.asList("John", "Mike"))
,用于查询name
属性不包含在"John"
和"Mike"
中的文档。
正则表达式:
Filters.regex("name", "^J.*n$")
,用于查询name
属性匹配正则表达式"^J.*n$"
的文档。
与:
Filters.and(Filters.eq("name", "John"), Filters.gt("age", 18))
,用于查询name
属性等于"John"
且age
属性大于18
的文档。
或:
Filters.or(Filters.eq("name", "John"), Filters.gt("age", 18))
,用于查询name
属性等于"John"
或age
属性大于18
的文档。
存在:
Filters.exists("name", true)
,用于查询存在name
属性的文档。
不存在:
Filters.exists("name", false)
,用于查询不存在name
属性的文档。
使用and()
和or()
方法来组合多个条件,例如:
类似于sql:`name = "john" and (age > 18 or age < 30)`
Bson filter = Filters.and( Filters.eq("name", "John"), Filters.or( Filters.gt("age", 18), Filters.lt("age", 30) ) );
3. 指定查询返回的字段
在 MongoDB 中,可以使用 projection
对查询返回的字段进行指定。通过指定 projection
,可以过滤掉不需要的字段,提高查询效率,并减小数据传输的大小。
在 Java 中,可以使用 Projections
类来进行字段的指定。该类提供了一些静态方法,可以方便地创建不同类型的投影表达式。以下是一些常用的示例:
返回指定字段
List<Document> results = collection.find().projection(Projections.include("name", "age")).into(new ArrayList<>());
上述代码中的 Projections.include("name", "age")
指定了只返回 name
和 age
两个字段。
排除指定字段
List<Document> results = collection.find().projection(Projections.exclude("address")).into(new ArrayList<>());
上述代码中的 Projections.exclude("address")
指定了不返回 address
字段。
限制返回字段
List<Document> results = collection.find().projection(Projections.slice("comments", 5)).into(new ArrayList<>());
上述代码中的 Projections.slice("comments", 5)
指定了只返回 comments
字段中的前五个元素。
进行计算并返回结果
List<Document> results = collection.find().projection(Projections.fields(Projections.include("name"), Projections.computed("agePlus10", "$age + 10"))).into(new ArrayList<>());
上述代码中的 Projections.computed("agePlus10", "$age + 10")
指定了将 age
字段加上 10 并将结果保存到名为 agePlus10
的新字段中。
其他的限制操作
1. Projections.elemMatch(String field, Bson filter)
该方法用于返回某个数组字段中符合特定条件的子文档。参数 field
指定了要查询的数组字段,filter
指定了查询条件。以下是一个示例:
List<Document> results = collection.find().projection(Projections.elemMatch("comments", Filters.eq("author", "John Doe"))).into(new ArrayList<>());
上述代码中,Projections.elemMatch("comments", Filters.eq("author", "John Doe"))
表示查询 comments
数组字段中 author
为 John Doe
的子文档,并返回符合条件的子文档。
2. Projections.metaTextScore(String metaTextScoreField)
该方法用于返回使用 $meta
操作符计算出来的文本搜索相关度得分。参数 metaTextScoreField
指定了保存文本搜索相关度得分的字段名称。以下是一个示例:
List<Document> results = collection.find(Filters.text("Java")).projection(Projections.metaTextScore("score")).sort(Sorts.metaTextScore("score")).into(new ArrayList<>());
上述代码中,Projections.metaTextScore("score")
表示使用 $meta
操作符计算出来的文本搜索相关度得分保存到 score
字段中。
3. Projections.excludeId()
该方法用于排除 _id
字段。以下是一个示例:
List<Document> results = collection.find().projection(Projections.excludeId()).into(new ArrayList<>());
4. Projections.excludeFields(Bson... fields)
该方法用于排除指定的字段。参数 fields
指定了要排除的字段列表。以下是一个示例:
List<Document> results = collection.find().projection(Projections.excludeFields("password", "email")).into(new ArrayList<>());
上述代码中,Projections.excludeFields("password", "email")
表示排除 password
和 email
两个字段。
4. 限制返回文档的数量
在 MongoDB 中,可以通过 limit()
方法来限制查询结果返回的文档数量。
limit()
方法接受一个整数参数,表示返回的文档数量。例如,以下代码限制查询结果只返回前 10 条文档:
FindIterable<Document> iterable = collection.find(); iterable.limit(10);
如果查询结果包含的文档数量小于指定的限制数,则返回实际包含的文档数。例如,如果查询结果只包含 5 个文档,但是限制返回文档数量为 10,则只会返回这 5 个文档。
跳过指定数量的文档
skip()
方法接受一个整数参数,表示要跳过的文档数量。例如,以下代码跳过查询结果中的前 5 个文档:
FindIterable<Document> iterable = collection.find(); iterable.skip(5);
如果查询结果包含的文档数量小于指定的跳过数,则返回一个空的文档集合。例如,如果查询结果只包含 3 个文档,但是要求跳过前 5 个文档,则返回一个空的文档集合。
分页查询:
FindIterable<Document> iterable = collection.find().sort(Sorts.descending("age")); iterable.skip(5).limit(10);
上述代码会先按照年龄逆序排序,然后跳过前 5 个文档,最后限制返回结果最多只有 10 个文档。
5. 排序
sort()
方法接受一个Bson
对象作为参数,表示排序的规则。通常,可以使用Sorts
类提供的静态方法来创建Bson
对象,例如:
collection.find().sort(Sorts.ascending("age"));
上述代码会按照年龄升序排序查询结果。
collection.find().sort(Sorts.descending("age"));
上述代码会按照年龄降序排序查询结果。
在 MongoDB 中,可以按照多个属性进行排序。例如,以下代码会先按照年龄升序排序,然后按照名称降序排序:
collection.find().sort(Sorts.ascending("age").descending("name"));
除了使用
Sorts
类提供的静态方法外,还可以使用OrderBy
类的方法来创建排序规则。例如,以下代码与前面的代码等效:
collection.find().sort(OrderBy.asc("age").desc("name"));
sort()
方法也可以和其他查询条件一起使用。例如,以下代码会查询年龄大于 18 岁的文档,并且按照年龄降序排序:
collection.find(Filters.gt("age", 18)).sort(Sorts.descending("age"));
6. 匹配嵌套文档
在 MongoDB 中,文档可以包含嵌套的文档,也就是一个文档中的某个字段的值是一个文档。查询这种嵌套文档需要使用嵌套查询操作符,例如 $elemMatch
。
假设有一个
users
集合,每个文档包含一个name
字段和一个favorites
字段,favorites
字段是一个数组,包含多个喜欢的电影名和电影类型:
{ "_id" : ObjectId("617f120110136e6f7c6e301d"), "name" : "Alice", "favorites" : [ { "title" : "Inception", "genre" : "Sci-Fi" }, { "title" : "The Shawshank Redemption", "genre" : "Drama" } ] } { "_id" : ObjectId("617f120110136e6f7c6e301e"), "name" : "Bob", "favorites" : [ { "title" : "The Godfather", "genre" : "Crime" }, { "title" : "The Dark Knight", "genre" : "Action" } ] }
要查询 Alice 喜欢的所有科幻电影,可以使用
$elemMatch
操作符:
collection.find(Filters.and(Filters.eq("name", "Alice"), Filters.elemMatch("favorites", Filters.eq("genre", "Sci-Fi"))));
上述代码会查询
name
为 "Alice" 并且favorites
数组中至少有一项的genre
字段是 "Sci-Fi" 的文档。
可以将 $elemMatch
操作符用在多层嵌套的文档中。例如,假设有一个 products
集合,每个文档包含一个 name
字段和一个 reviews
字段,reviews
字段是一个数组,包含多个评价文档,每个评价文档又包含一个 comments
字段和一个 score
字段:
{ "_id" : ObjectId("6181a77a2b59f5df0e13d7c4"), "name" : "iPhone", "reviews" : [ { "comments" : "Good", "score" : 8 }, { "comments" : "Bad", "score" : 2 } ] } { "_id" : ObjectId("6181a77a2b59f5df0e13d7c5"), "name" : "iPad", "reviews" : [ { "comments" : "Very good", "score" : 9 }, { "comments" : "Not bad", "score" : 6 } ] }
要查询评分大于 7 分的
iPad
评价文档的所有评论,可以使用多层嵌套的$elemMatch
操作符:
collection.find(Filters.and(Filters.eq("name", "iPad"), Filters.elemMatch("reviews", Filters.elemMatch("comments", Filters.gt("score", 7)))));
7. 使用聚合管道
MongoDB聚合管道是指将多个数据处理操作组合在一起以形成数据处理管道,以便更有效地查询和处理数据。聚合管道可以用于实现许多常见的数据处理操作,例如过滤、排序、分组、计数、平均值、求和、求最大/最小值等。
在Java中,我们可以使用MongoDB的聚合管道API来执行聚合查询。以下是一个使用聚合管道查询的示例代码:
MongoCollection<Document> collection = database.getCollection("users"); List<Document> pipeline = Arrays.asList( new Document("$match", new Document("age", new Document("$gt", 30))), new Document("$group", new Document("_id", "$gender").append("count", new Document("$sum", 1))), new Document("$sort", new Document("count", -1)), new Document("$limit", 10) ); MongoCursor<Document> cursor = collection.aggregate(pipeline).iterator(); while (cursor.hasNext()) { Document doc = cursor.next(); System.out.println(doc.toJson()); }
在这个示例中,我们首先获取了名为“users”的集合,然后使用一个管道列表定义了我们的聚合查询。该管道由四个操作组成:
$match
:过滤年龄大于30岁的文档。$group
:按性别分组,并计算每个组中文档的数量。$sort
:按文档数量进行排序,以便按数量最多的顺序返回结果。$limit
:限制结果数量为10。
最后,我们使用aggregate
方法执行查询,并使用迭代器遍历查询结果并打印输出。
8. 分组查询
分组查询是 MongoDB 中非常有用的一种聚合操作,它可以将文档集合按照某个字段进行分组,然后对每组进行统计分析,例如计算每个分组内文档数量的总和、平均值、最大值、最小值等等。下面介绍如何在 Java 代码中使用 MongoDB 进行分组查询。
首先,我们需要使用 Aggregation 类中的 group() 方法进行分组操作。该方法接受一个 Bson 类型的参数,表示分组条件。例如,下面的代码将按照 name 字段进行分组:
Bson group = Aggregates.group("$name");
接下来,我们可以使用 Aggregation 类中的各种聚合方法对每个分组进行统计分析。例如,下面的代码将在每个分组中计算 age 字段的平均值:
Bson avgAge = Aggregates.avg("age", "$age");
最后,我们可以使用 Aggregation 类中的 pipeline() 方法将所有的聚合操作串联起来,从而得到最终的结果。例如,下面的代码将按照 name 字段进行分组,并在每个分组中计算 age 字段的平均值:
List<Bson> pipeline = Arrays.asList( Aggregates.group("$name", Aggregates.avg("age", "$age")) ); MongoCollection<Document> collection = database.getCollection("users"); MongoCursor<Document> cursor = collection.aggregate(pipeline).iterator(); while (cursor.hasNext()) { Document result = cursor.next(); System.out.println(result.toJson()); }
在上面的代码中,我们使用 pipeline() 方法将分组操作和计算平均值操作串联起来,然后使用 aggregate() 方法执行聚合操作,并将结果输出到控制台上。
除了平均值之外,Aggregation 类中还提供了各种聚合方法,例如 sum()、count()、max()、min() 等等,可以根据实际需求进行选择。
总结
到此这篇关于Java查询MongoDB数据库的文章就介绍到这了,更多相关Java查询MongoDB案例内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!