MongoDB嵌入式文档数组:仅获取一个具有特定属性的嵌入式文档

海神:

我想从一个带有mongodb和spring boot的数组中获取具有特定字段(版本)的嵌入式文档。这是数据结构:

{
   "_id": 5f25882d28e40663719d0b52,
   "versions": [
       {
           "versionNr": 1
           "content": "This is the first Version of some Text"
       },
       {
           "versionNr": 2
           "content": "This is the second Version of some Text"
       },
       ...
   ]
   ...
}

这是我的实体:

@Data
@Document(collection = "letters")
public class Letter {
  @Id
  @Field("_id")
  private ObjectId _id;
  
  @Field("versions")
  private List<Version> versions;
}

//There is no id for embedded documents 
@Data
@Document(collection = "Version")
public class Version{

  @Field("content")
  private String content;
  
  @Field("version")
  private Long version;
}

这是行不通的查询。我认为“加入”是不正确的。但是找不到正确的方法。

public Optional<Version> findByIdAndVersion(ObjectId id, Long version) {
        Query query = new Query(Criteria.where("_id").is(id).and("versions.version").is(version));
        return Optional.ofNullable(mongoTemplate.findOne(query,Version.class,"letters"));
    }
}

编辑:这是一个工作的聚合,我敢肯定这不是一个很好的解决方案,但它可以工作

@Override
    public Optional<Version> findByIdAndVersion(ObjectId id, Long version) {

        MatchOperation match = new MatchOperation(Criteria.where("_id").is(id).and("versions.version").is(version));
        Aggregation aggregate = Aggregation.newAggregation(
                match,
                Aggregation.unwind("versions"),
                match,
                Aggregation.project()
                        .andInclude("versions.content")
                        .andInclude("versions.version")
        );

        AggregationResults<Version> aggregateResult = mongoTemplate.aggregate(aggregate, "letters", Version.class);
        Version version = aggregateResult.getUniqueMappedResult();
        return Optional.ofNullable(mongoRawPage);
    }
梦中梦:
Query query = new Query(Criteria.where("_id").is(id).and("versions.version").is(version));
return Optional.ofNullable(mongoTemplate.findOne(query,Version.class,"letters"));

您正在查询Letter文档,但是您的实体类被指定为Version.class,因为MongoDB中的findOne不会单独返回子文档而是返回整个文档,因此您需要将Letter.class作为返回类型和过滤器(项目)什么领域回来。因此,您可以投影要接收的单个版本子文档,如下所示:

Query query = new Query()
            .addCriteria(Criteria.where("_id").is(id).and("versions.version").is(version))
            .fields().position("versions", 1);
Optional.ofNullable(mongoTemplate.findOne(query, Letter.class))
        .map(Letter::getVersions)
        .findFirst()
        .orElse(null);

或使用聚合管道:

newAggregation(
        Letter.class,
        match(Criteria.where("_id").is(id)),
        unwind("versions"),
        replaceRoot("versions"),
        match(Criteria.where("version").is(version))), 
    Version.class)

注意-我是即时输入的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章