Я хочу получить один встроенный документ с определенным полем (версией) c из массива с 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);
}