如何在MongoDB中查询以material开头的动态字段?
批量获取MongoDB中所有以指定前缀开头的字段
Spring Data MongoDB的Query.fields().include()并不支持直接使用通配符(比如你尝试的material*),不过有两种实用的方法可以批量包含所有以material开头的字段:
方法1:先提取所有匹配字段再批量添加
先通过聚合查询获取集合中所有存在的字段,过滤出material开头的字段后,再循环添加到查询的包含列表中。
代码实现
@Autowired private MongoTemplate mongoTemplate; public List<Document> getMaterialRelatedData() { // 1. 聚合查询获取集合中所有字段 Aggregation aggregation = Aggregation.newAggregation( Aggregation.project().andExclude("_id"), Aggregation.addFields().addField("fields").withValue(Aggregation.objectToArray("$$ROOT")).build(), Aggregation.unwind("fields"), Aggregation.group().addToSet("fields.k").as("allFields"), Aggregation.project("allFields").andExclude("_id") ); AggregationResults<Document> fieldResults = mongoTemplate.aggregate(aggregation, "your_collection_name", Document.class); Set<String> allFields = fieldResults.getUniqueMappedResult().get("allFields", Set.class); // 2. 过滤出以material开头的字段 Set<String> materialFields = allFields.stream() .filter(field -> field.startsWith("material")) .collect(Collectors.toSet()); // 3. 构建查询并批量包含字段 Query query = new Query(); materialFields.forEach(query.fields()::include); return mongoTemplate.find(query, Document.class, "your_collection_name"); }
方法2:使用聚合管道动态指定包含规则
利用MongoDB原生聚合的$project阶段支持通配符的特性,直接动态保留所有material开头的字段。
代码实现
@Autowired private MongoTemplate mongoTemplate; public List<Document> getMaterialFieldsViaAggregation() { // 构建$project阶段:保留所有material开头的字段(可按需保留_id或其他字段) Document projectStage = new Document("$project", new Document() .append("_id", 1) // 不需要的话可以删除这一行 .append("material*", 1) ); Aggregation aggregation = Aggregation.newAggregation( Aggregation.customAggregationOperation(context -> projectStage) ); return mongoTemplate.aggregate(aggregation, "your_collection_name", Document.class).getMappedResults(); }
注意事项
- 方法1适合字段结构稳定的场景,会收集集合中所有出现过的
material前缀字段;如果文档字段差异大,也能覆盖所有可能的匹配字段。 - 方法2更高效,但要求MongoDB版本在3.6及以上(支持通配符查询)。
- 记得将代码中的
your_collection_name替换为实际的集合名称。
内容的提问来源于stack exchange,提问作者Zeeshan Ali
相关产品推荐
相关产品推荐

