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

时间:2018-10-23 09:43:48

标签: java mongodb spring-boot

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

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

public Class Employee
{
private String Id;
private String Name;
.
.

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

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

然后我将遍历每个员工对象以获取员工ID并保存在List<String>

现在,我希望以一种可以一次性检索所有ID的方式解决问题。类似-:

List<String> employeeId = someCodeHere; 

请帮助

谢谢。

3 个答案:

答案 0 :(得分:1)

您可以使用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();

那么您无需在stream()内部调用getEmployeeIds()方法。

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

答案 1 :(得分:1)

根据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进行过滤。

为了将可迭代的结果集转换为请求的String对象列表,可以使用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

答案 2 :(得分:0)

一年后,您可以使用以下代码完成所需的操作:

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

无需进行任何转换。我遇到了同样的情况,并解决了这个问题。