-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Dear spring-data-mongodb maintenance team,
I am having trouble with the projection of fields in nested lists with spring-data-mongodb.
Given the following minimal example mongoDB:
db.nestedList.insertOne(
{
"flat": 1,
"flatDescription": "one",
"list": [
{
"element": 11,
"description": "eleven"
},
{
"element": 12,
"description": "twelve"
}
]
}
);
db.nestedList.insertOne(
{
"flat": 2,
"flatDescription": "two",
"list": [
{
"element": 21,
"description": "twentyone"
},
{
"element": 22,
"description": "twentytwo"
}
]
}
);
Let's assume I only want to know about the fields "flat" and all "list.element". In mongoDB I can simply execute
db.nestedList
.find({})
.projection({ flat: 1, "list.element" : 1})
with the result
{
"_id" : ObjectId("649a8045da17a6faee05e306"),
"flat" : 1,
"list" : [
{
"element" : 11
},
{
"element" : 12
}
]
},
{
"_id" : ObjectId("649a80a9da17a6faee05e307"),
"flat" : 2,
"list" : [
{
"element" : 21
},
{
"element" : 22
}
]
}
This is exactly my expected and desired behavior!
Now my question is: How can I achieve this exact behavior with Spring Data (Java)?
The intuitive approach
ProjectionOperation projection = Aggregation.project("flat", "list.element");
generates
{ "flat" : "$flat", "element" : "$list.element"}
which produces
{
"_id" : ObjectId("649a8045da17a6faee05e306"),
"flat" : 1,
"element" : [ 11, 12 ]
},
{
"_id" : ObjectId("649a80a9da17a6faee05e307"),
"flat" : 2,
"element" : [ 21, 22 ]
}
which is obviously not what I need, as element is now a property in the root object and also is an array.
Slightly better
ProjectionOperation projection = Aggregation.project("flat");
projection = projection.and("list.element").as("list.element");
generates
{ "flat" : "$flat", "list.element" : "$list.element"}
which produces
{
"_id" : ObjectId("649a8045da17a6faee05e306"),
"list" : [
{
"element" : [ 11, 12 ]
},
{
"element" : [ 11, 12 ]
}
],
"flat" : 1
},
{
"_id" : ObjectId("649a80a9da17a6faee05e307"),
"list" : [
{
"element" : [ 21, 22 ]
},
{
"element" : [ 21, 22 ]
}
],
"flat" : 2
}
which is still wrong. At list the structure is correct now but list.element are still arrays.
I even tried
ProjectionOperation projection = Aggregation.project("flat");
projection = projection.and("list").nested(Fields.fields("list.element"));
generates
{ "_id" : "$_id", "list" : { "element" : "$list.element"}}
which produces
{
"list" : [
{
"element" : [ 11, 12 ]
},
{
"element" : [ 11, 12 ]
}
],
"_id" : ObjectId("649a8045da17a6faee05e306")
},
{
"list" : [
{
"element" : [ 21, 22 ]
},
{
"element" : [ 21, 22 ]
}
],
"_id" : ObjectId("649a80a9da17a6faee05e307")
}
which is still wrong as list.element are arrays.
Is this a bug or am I just using it wrong? In the latter case, can you please explain the proper usage? :)
I am looking forward to you response!
Kind regards,
fkreis