杰瑞科技汇

MongoDB Java条件查询怎么写?

添加依赖

确保你的 Java 项目中已经添加了 MongoDB Java 驱动的依赖,如果你使用的是 Maven,请在 pom.xml 中添加以下依赖:

MongoDB Java条件查询怎么写?-图1
(图片来源网络,侵删)
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>4.11.1</version> <!-- 建议使用最新稳定版 -->
</dependency>

基础连接与查询

在执行任何查询之前,我们需要先连接到 MongoDB 数据库。

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
public class MongoConnection {
    public static void main(String[] args) {
        // 替换为你的 MongoDB 连接字符串
        String uri = "mongodb://localhost:27017";
        try (MongoClient mongoClient = MongoClients.create(uri)) {
            // 连接到指定的数据库
            MongoDatabase database = mongoClient.getDatabase("mydb");
            // 获取指定的集合
            MongoCollection<Document> collection = database.getCollection("users");
            System.out.println("成功连接到 MongoDB 并获取集合。");
            // 后续的查询代码将在这里...
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

核心概念:FiltersFindIterable

在 Java 驱动中,条件查询主要通过两个核心类来实现:

  • Filters: 一个工具类,用于构建各种查询条件(相当于 MongoDB 查询操作符,如 $gt, $lt, $eq 等)。
  • FindIterable<T>: 表示一个可迭代的查询结果集,你通过 collection.find() 方法获取它,并可以链式调用各种方法来配置查询(如排序、分页、投影等)。

常用条件查询示例

假设我们的 users 集合中有如下数据:

[
  { "_id": 1, "name": "Alice", "age": 25, "city": "New York", "interests": ["reading", "hiking"] },
  { "_id": 2, "name": "Bob", "age": 30, "city": "London", "interests": ["gaming", "coding"] },
  { "_id": 3, "name": "Charlie", "age": 25, "city": "New York", "interests": ["music", "reading"] },
  { "_id": 4, "name": "David", "age": 35, "city": "Paris", "interests": ["coding", "traveling"] },
  { "_id": 5, "name": "Eve", "age": null, "city": "Tokyo", "interests": ["anime"] }
]

示例 1: 精确查询 ($eq)

查询 city 为 "New York" 的所有用户。

MongoDB Java条件查询怎么写?-图2
(图片来源网络,侵删)
// 创建查询条件:city 等于 "New York"
Bson filter = Filters.eq("city", "New York");
// 执行查询
FindIterable<Document> findIterable = collection.find(filter);
// 遍历并打印结果
for (Document doc : findIterable) {
    System.out.println(doc.toJson());
}

示例 2: 比较查询

查询 age 大于 28 的用户。

// age > 28
Bson filter = Filters.gt("age", 28);
printResults(collection.find(filter));

查询 age 小于或等于 30 的用户。

// age <= 30
Bson filter = Filters.lte("age", 30);
printResults(collection.find(filter));

查询 age 在 25 到 30 之间(包含25和30)的用户。

// 25 <= age <= 30
Bson filter = Filters.and(Filters.gte("age", 25), Filters.lte("age", 30));
printResults(collection.find(filter));

示例 3: 逻辑查询 (and, or, not)

查询 city 为 "New York" 并且 age 为 25 的用户。

// city = "New York" AND age = 25
Bson filter = Filters.and(
    Filters.eq("city", "New York"),
    Filters.eq("age", 25)
);
printResults(collection.find(filter));

查询 city 为 "New York" 或者 city 为 "London" 的用户。

// city = "New York" OR city = "London"
Bson filter = Filters.or(
    Filters.eq("city", "New York"),
    Filters.eq("city", "London")
);
printResults(collection.find(filter));

查询 name 不等于 "Alice" 的用户。

// name != "Alice"
Bson filter = Filters.ne("name", "Alice");
printResults(collection.find(filter));

示例 4: 模糊查询 (regex)

查询 name 以 "A" 开头的用户。

// name 以 "A" 开头,不区分大小写
Bson filter = Filters.regex("name", "^A", "i");
printResults(collection.find(filter));

示例 5: 查询数组 (in, all, size)

查询 interests 包含 "reading" 的用户。

// interests 数组中包含 "reading" 元素
Bson filter = Filters.all("interests", "reading");
printResults(collection.find(filter));

查询 city 是 "New York", "London", 或 "Paris" 之一的用户。

// city 在 ["New York", "London", "Paris"] 列表中
Bson filter = Filters.in("city", "New York", "London", "Paris");
printResults(collection.find(filter));

查询 interests 数组长度恰好为 2 的用户。

// interests 数组的大小为 2
Bson filter = Filters.size("interests", 2);
printResults(collection.find(filter));

示例 6: 查询 null

查询 agenull 的用户。

// age IS NULL
Bson filter = Filters.eq("age", null);
printResults(collection.find(filter));

示例 7: 查询字段是否存在 (exists)

查询存在 age 字段的用户。

// age 字段存在
Bson filter = Filters.exists("age", true);
printResults(collection.find(filter));

查询不存在 age 字段的用户。

// age 字段不存在
Bson filter = Filters.exists("age", false);
printResults(collection.find(filter));

高级查询功能

1 投影 (projection)

只返回需要的字段,而不是整个文档。

// 查询 city 为 "New York" 的用户,但只返回 name 和 age 字段,_id 默认返回
// 1 表示包含,0 表示排除
Bson filter = Filters.eq("city", "New York");
Bson projection = new Document("name", 1).append("age", 1);
FindIterable<Document> findIterable = collection.find(filter).projection(projection);
for (Document doc : findIterable) {
    System.out.println(doc.toJson()); // 输出: {"_id": 1, "name": "Alice", "age": 25} 等
}

2 排序 (sort)

age 字段升序排列。

// 按 age 升序 (1 表示升序, -1 表示降序)
Bson sort = new Document("age", 1);
printResults(collection.find().sort(sort));

3 分页 (skiplimit)

跳过前 2 条记录,然后只取 2 条记录(实现分页,第2页,每页2条)。

// 跳过 2 条,限制返回 2 条
FindIterable<Document> findIterable = collection.find().skip(2).limit(2);
printResults(findIterable);

4 获取单个文档 (first()findOne())

只查询满足条件的第一个文档。

// 使用 first()
Document firstDoc = collection.find(Filters.eq("city", "London")).first();
if (firstDoc != null) {
    System.out.println("找到第一个文档: " + firstDoc.toJson());
}
// 或者使用 findOne() (推荐,更语义化)
Document oneDoc = collection.find(Filters.eq("city", "London")).first();
if (oneDoc != null) {
    System.out.println("找到第一个文档: " + oneDoc.toJson());
}

完整可运行的示例

这是一个将上述所有概念整合在一起的完整示例。

import com.mongodb.client.*;
import com.mongodb.client.model.Filters;
import org.bson.Document;
public class MongoQueryExample {
    public static void main(String[] args) {
        String uri = "mongodb://localhost:27017";
        try (MongoClient mongoClient = MongoClients.create(uri)) {
            MongoDatabase database = mongoClient.getDatabase("mydb");
            MongoCollection<Document> collection = database.getCollection("users");
            // 1. 插入一些测试数据 (如果集合为空)
            insertTestData(collection);
            System.out.println("--- 1. 查询 city 为 'New York' 的用户 ---");
            Bson filter1 = Filters.eq("city", "New York");
            printResults(collection.find(filter1));
            System.out.println("\n--- 2. 查询 age > 28 的用户 ---");
            Bson filter2 = Filters.gt("age", 28);
            printResults(collection.find(filter2));
            System.out.println("\n--- 3. 查询 city 为 'New York' AND age 为 25 的用户 ---");
            Bson filter3 = Filters.and(Filters.eq("city", "New York"), Filters.eq("age", 25));
            printResults(collection.find(filter3));
            System.out.println("\n--- 4. 查询 interests 包含 'reading' 的用户 ---");
            Bson filter4 = Filters.all("interests", "reading");
            printResults(collection.find(filter4));
            System.out.println("\n--- 5. 查询 name 以 'A' 开头的用户 (不区分大小写) ---");
            Bson filter5 = Filters.regex("name", "^A", "i");
            printResults(collection.find(filter5));
            System.out.println("\n--- 6. 查询 city 为 'New York' 或 'London' 的用户,并按 age 降序排序 ---");
            Bson filter6 = Filters.in("city", "New York", "London");
            // 按 age 降序 (-1)
            Bson sort6 = new Document("age", -1);
            printResults(collection.find(filter6).sort(sort6));
            System.out.println("\n--- 7. 查询 age 为 null 的用户 ---");
            Bson filter7 = Filters.eq("age", null);
            printResults(collection.find(filter7));
            System.out.println("\n--- 8. 分页查询: 跳过1条,取2条 ---");
            printResults(collection.find().skip(1).limit(2));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static void printResults(FindIterable<Document> findIterable) {
        for (Document doc : findIterable) {
            System.out.println(doc.toJson());
        }
    }
    private static void insertTestData(MongoCollection<Document> collection) {
        // 清空集合
        collection.deleteMany(new Document());
        // 插入测试数据
        collection.insertMany(List.of(
            new Document("_id", 1).append("name", "Alice").append("age", 25).append("city", "New York").append("interests", List.of("reading", "hiking")),
            new Document("_id", 2).append("name", "Bob").append("age", 30).append("city", "London").append("interests", List.of("gaming", "coding")),
            new Document("_id", 3).append("name", "Charlie").append("age", 25).append("city", "New York").append("interests", List.of("music", "reading")),
            new Document("_id", 4).append("name", "David").append("age", 35).append("city", "Paris").append("interests", List.of("coding", "traveling")),
            new Document("_id", 5).append("name", "Eve").append("age", null).append("city", "Tokyo").append("interests", List.of("anime"))
        ));
        System.out.println("测试数据已插入/清空。");
    }
}
查询类型 Java (Filters) 方法 MongoDB Shell (Query)
等于 Filters.eq("field", value) { field: value }
大于 Filters.gt("field", value) { field: { $gt: value } }
小于 Filters.lt("field", value) { field: { $lt: value } }
大于等于 Filters.gte("field", value) { field: { $gte: value } }
小于等于 Filters.lte("field", value) { field: { $lte: value } }
不等于 Filters.ne("field", value) { field: { $ne: value } }
Filters.and(cond1, cond2, ...) { $and: [ {cond1}, {cond2} ] }
Filters.or(cond1, cond2, ...) { $or: [ {cond1}, {cond2} ] }
包含 (数组) Filters.all("field", val1, val2) { field: { $all: [val1, val2] } }
在...中 (列表) Filters.in("field", val1, val2) { field: { $in: [val1, val2] } }
正则 Filters.regex("field", pattern, options) { field: { $regex: pattern, $options: options } }
字段存在 Filters.exists("field", boolean) { field: { $exists: boolean } }
为 null Filters.eq("field", null) { field: null }

通过掌握 FiltersFindIterable 的各种方法,你就可以在 Java 中灵活地构建任何复杂的 MongoDB 查询。

分享:
扫描分享到社交APP
上一篇
下一篇