如何使用MongoDB Java驱动按嵌入数组筛选可用座位数>3的文档
解决MongoDB查询可用座位数大于3的文档问题
当然可行!要实现你想要的「统计seats数组中available: true的元素数量大于3」的查询,我们可以利用MongoDB的聚合框架或者3.6+版本支持的$expr查询语法,下面是对应mongodb-java-driver的具体实现方案:
方案一:使用聚合框架(兼容性更广)
这种方式适合所有支持聚合操作的MongoDB版本,核心思路是先计算每个文档的可用座位数,再过滤出数量符合要求的文档:
import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Filters; import org.bson.Document; import java.util.Arrays; public class MongoQueryExample { public static void main(String[] args) { try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { MongoDatabase db = mongoClient.getDatabase("your_database_name"); MongoCollection<Document> collection = db.getCollection("your_collection_name"); var pipeline = Arrays.asList( // 添加字段计算可用座位数量 Aggregates.addFields(new Document("availableSeatsCount", new Document("$size", new Document("$filter", new Document("input", "$seats") .append("as", "seat") .append("cond", new Document("$eq", Arrays.asList("$$seat.available", true))) ) ) )), // 过滤可用座位数大于3的文档 Aggregates.match(Filters.gt("availableSeatsCount", 3)) ); collection.aggregate(pipeline).forEach(doc -> System.out.println(doc.toJson())); } } }
方案二:使用$expr简化查询(MongoDB 3.6+)
如果你的MongoDB版本在3.6及以上,可以直接在find查询中使用$expr内嵌聚合表达式,无需走聚合管道,代码更简洁:
import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.Filters; import org.bson.Document; import java.util.Arrays; public class MongoFindExample { public static void main(String[] args) { try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { MongoDatabase db = mongoClient.getDatabase("your_database_name"); MongoCollection<Document> collection = db.getCollection("your_collection_name"); // 构建查询条件:统计seats中available为true的数量 > 3 var query = Filters.expr( new Document("$gt", Arrays.asList( new Document("$size", new Document("$filter", new Document("input", "$seats") .append("as", "seat") .append("cond", new Document("$eq", Arrays.asList("$$seat.available", true))) ) ), 3 )) ); collection.find(query).forEach(doc -> System.out.println(doc.toJson())); } } }
关键逻辑说明
$filter:遍历seats数组,筛选出所有available: true的座位元素,生成一个新的子数组。$size:获取这个过滤后的子数组的长度,也就是可用座位的数量。$gt:判断这个数量是否大于3,满足条件的文档才会被返回。
针对你给出的示例文档,因为它的可用座位数是3,所以不会被上述查询匹配返回;只有当文档中available: true的座位数量大于3时,才会被查询出来。
内容的提问来源于stack exchange,提问作者ms1403
相关产品推荐
相关产品推荐

