Can't use sub-document fields in Spring data mongodb $graphLookup

Viewed 456

The documents in the collection test_links looks:

{ 
    "_id" : "57:58", 
    "from" : {
    "orgunitType" : "Regional", 
    "refId" : "57", 
    "name" : "Root Node"
}, 
    "to" : {
    "orgunitType" : "Department", 
    "refId" : "58", 
    "name" : "Department1"
}, 
"active" : true, 
}

While trying to implement a MongoDB aggregation query:

db.test_links.aggregate([
        {$match: {"to.refId":"64"}},
        {$graphLookup:{
             from: "test_links",
             startWith: "$to.refId",
             connectFromField: "from.refId",
             connectToField: "to.refId",
             as: "parents"
        }}]);

As Spring Data MongoDB:

Aggregation agg = Aggregation.newAggregation(match(where("to.refId").is(id)),
    graphLookup("test_links").startWith("$to.refId").connectFrom("from.refId")
        .connectTo("to.refId").as("parent")
);
AggregationResults results = infraTemplate.aggregate(agg, "test_links", Map.class);

The connectFrom and connectTo field values (from.refId, to.refId) replaced with refId ("from" and "to" stripped). As a result, query doesn't return any results. Constructor of AggregationField class keeps original name in target field and set name stripped ("refId"). The problem is that GraphLookupOperation.toDocument method uses field.getName() instead of field.getTarget():

...
graphLookup.put("connectFromField", connectFrom.getName()); 
graphLookup.put("connectToField", connectTo.getName());
...

Is there a workaround? And will it be fixed in future versions? I understand that I can create my own CustomAggregationOperation, but it will be nice to use things out-of-box feature, if somebody tried to develop it.

Spring Data MongoDB version 2.0.0.M4

1 Answers

In spring-boot-starter-data-mongodb\1.5.4.RELEASE same behaviour, not sure is it expected to be such, but I found workaround.

Problem with connectToField: "to.refId" is that here used embedded value, by providing full path to that field all works fine, as expected, so should be changed to: connectToField: "COLLECTION_NAME.to.refId"

Related