如何从 MongoDB 中检索特定的元素列表?

Posted

技术标签:

【中文标题】如何从 MongoDB 中检索特定的元素列表?【英文标题】:How do I retrieve particular List of element from MongoDB? 【发布时间】:2019-03-27 12:12:33 【问题描述】:

我想从 Mongodb 表中检索特定的元素列表。

假设我的 Employee 类中有两个变量:

public Class Employee

private String Id;
private String Name;
.
.

现在当我进行 fetch 查询时,它将类似于 -:

List<Employee> list=mongoTemplate.findAll();

然后我将遍历每个员工对象以获取员工 ID 并保存在 List&lt;String&gt;

现在,我想要这样一种解决方案,即我可以一次性检索所有 ID。类似于:

List<String> employeeId = someCodeHere; 

如果可以的话请帮忙

提前致谢。

【问题讨论】:

试试Query query = new Query(); query.fields().include("Id"); List&lt;String&gt; employeeIds = mongoTemplate.find(query , String.class); 感谢@Veeram 的回复.. 【参考方案1】:

一年后,你想要的可以用下面的代码完成:

List<String> employeeIds= mongoTemplate.query(Employee.class).distinct("id").as(String.class).all();

无需进行任何转换。我有同样的情况并解决了它。

【讨论】:

【参考方案2】:

你可以使用Java Stream API:

private List<String> getEmployeeIds() 
  return mongoTemplate.findAll().stream()
    .map(Employee::getId)
    .filter(Objects::nonNull)
    .collect(toList());

首先查询所有员工,然后转换为流,将Employee 映射到Id,然后将所有non-null 值聚合到一个列表中。

如果您的 Repository 使用 Java 流 query method:

Stream<Employee> findAll();

那么您就不需要在getEmployeeIds() 中调用stream() 方法。

编辑:添加了从流中过滤空值

【讨论】:

感谢鲍里斯的回复 你能告诉我如何确保空值没有添加到我们的列表中吗? @RishabhBansal 您可以使用它从列表中删除空值list.removeAll(Collections.singleton(null)); 但是当你使用 Streams 这就是答案.filter(Objects::nonNull) @Boris 这是最优的吗?我的意思是有没有办法在数据库查询中做到这一点?【参考方案3】:

根据Mongos Reference documentation on distinct操作:

在单个集合或视图中查找指定字段的不同值,并在数组中返回结果。

在 Spring Data MongoDB 中可以这样实现:

DistinctIterable<String> distinctIds =
    mongoTemplate.getCollection(mongoTemplate.getCollectionName(Employee.class))
    .distinct("id", String.class);

return Lists.newArrayList(distinctIds);

// or

BasicDBObject dbObject = new BasicDBObject();
dbObject.append("name", new BasicDBObject("$regex", ".*and.*"));

DistinctIterable<String> distinctIds =
    mongoTemplate.getCollection(mongoTemplate.getCollectionName(Employee.class))
    .distinct("id", dbObject, String.class);

return Lists.newArrayList(distinctIds);

MongoTemplate 在这里提供了一些不同的重载。初级查询将直接收集员工集合条目的所有 ID,而后者将仅对名称中包含 and 的员工 ID 执行过滤。

为了将可迭代结果集转换为请求的字符串对象列表,您可以使用Guava's newArray(...) feature。

正如@Veeram 在他的评论中也提到的那样,您当然也可以使用投影查询,例如

Query query = Query.query(Criteria.where(...));
query.fields().include("id");

return mongoTemplate.find(query, String.class);

其中query.fields().include("id") 用于指定您实际感兴趣的字段。

distinct 相比,此方法将在结果列表中包含重复条目(如果有的话)。虽然 ID 通常应该是唯一的,但是对名称执行这两个查询可能会产生包含多个相同条目的结果。

虽然@Boris 给出的答案在技术上也是有效的,但不幸的是,它可能会对性能产生一些影响,尤其是如果还需要检索大量嵌入和引用的文档时。因此,我不推荐这种方法。

最后说明:在整个示例中,我将IdName 字段保留为小写字母,因为这基本上是Java naming convention。

【讨论】:

以上是关于如何从 MongoDB 中检索特定的元素列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 中使用特定日期范围和聚合从 MongoDB 数据库中检索数据?

如何从较大列表中的特定列表中检索特定值?

如何从 MongoDB 数组中检索第一个和最后一个元素并将其设置为不同的字段?

如何从数组中读取特定元素,该元素是来自 mongodb 的车把文件中对象的一部分?

如何在 Mongoose NodeJS 中使用聚合从数组中检索特定元素

MongoDB:仅检索特定记录[重复]