내 프로필 데이터가 아래처럼 보이면 userName과 productId의 조합에 대한 프로필을 으로 찾고이 제품에 대한 해당 계약의 프로필 만 반환하고 싶습니다.morphia로 mongo 문서에 임베디드 배열을 필터링하는 방법
{
"firstName": "John",
"lastName": "Doe",
"userName": "[email protected]",
"language": "NL",
"timeZone": "Europe/Amsterdam",
"contracts": [
{
"contractId": "DEMO1-CONTRACT",
"productId": "ticket-api",
"startDate": ISODate('2016-06-29T09:06:42.391Z'),
"roles": [
{
"name": "Manager",
"permissions": [
{
"activity": "ticket",
"permission": "createTicket"
},
{
"activity": "ticket",
"permission": "updateTicket"
},
{
"activity": "ticket",
"permission": "closeTicket"
}
]
}
]
},
{
"contractId": "DEMO2-CONTRACT",
"productId": "comment-api",
"startDate": ISODate('2016-06-29T10:27:45.899Z'),
"roles": [
{
"name": "Manager",
"permissions": [
{
"activity": "comment",
"permission": "createComment"
},
{
"activity": "comment",
"permission": "updateComment"
},
{
"activity": "comment",
"permission": "deleteComment"
}
]
}
]
}
]
}
해결 방법은 명령 줄에서 찾을 수 있습니다. 그러나 Morphia (최신 버전)를 사용하여이를 수행하는 방법을 찾는 것 같지 않습니다.
db.Profile.aggregate([
{ $match: {"userName": "[email protected]"}},
{ $project: {
contracts: {$filter: {
input: '$contracts',
as: 'contract',
cond: {$eq: ['$$contract.productId', "ticket-api"]}
}}
}}
])
이것은 내가 지금까지 가지고있는 것입니다. 어떤 도움을 가장 사이에 나는 집계 파이프 라인을 사용하지 않는 다른 해결책을 발견 ...
Query<Profile> matchQuery = getDatastore().createQuery(Profile.class).field(Profile._userName).equal(userName);
getDatastore()
.createAggregation(Profile.class)
.match(matchQuery)
.project(Projection.expression(??))
참고 감사합니다.
public Optional<Profile> findByUserNameAndContractQuery(String userName, String productId) {
DBObject contractQuery = BasicDBObjectBuilder.start(Contract._productId, productId).get();
Query<Profile> query =
getDatastore()
.createQuery(Profile.class)
.field(Profile._userName).equal(userName)
.filter(Profile._contracts + " elem", contractQuery)
.retrievedFields(true, Profile._contracts + ".$");
return Optional.ofNullable(query.get());
}