【问题标题】:How do I retrieve particular List of element from MongoDB?如何从 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 的回复..

标签: java mongodb spring-boot


【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-10
      • 2020-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多