I'm using Spring (boot) data 2.2.7 with mongodb 4.0. I've set 3 collections that I'm trying to join via an aggregation lookup operation.
- catalog
- stock
- operations
catalog
{
"_id" : ObjectId("5ec7856eb9eb171b72f721af"),
"model" : "HX711",
"type" : "DIGITAL",
....
}
mapped by
@Document(collection = "catalog")
public class Product implements Serializable {
@Id
private String _id;
@TextIndexed
private String model;
....
stock
{
"_id" : ObjectId("5ec78573b9eb171b72f721ba"),
"serialNumber" : "7af646bb-a5a8-4b86-b56b-07c12a625265",
"bareCode" : "72193.67751691974",
"productId" : "5ec7856eb9eb171b72f721af",
......
}
mapped by
@Document(collection = "stock")
public class Component implements Serializable {
@Id
private String _id;
private String productId;
....
the productId field refers to the _id one in the catalog collection
operations
{
"_id" : ObjectId("5ec78671b9eb171b72f721d3"),
"componentId" : ""5ec78573b9eb171b72f721ba",
.....
}
mapped by
public class Node implements Serializable {
@Id
private String _id;
private String componentId;
....
the componentId field refers to the _id one in the stock collection
I want to query operations or stock collection to retreive the corresponding Node or Component object list ordered by the Product.model field (in the catalog collection.)
While the goal is to code in Java I've tried to make the request first in the Mongo shell but I can't even get it working as I'm trying to join (lookup) a string with an ObjectId : Node.componentId -> Component._id Component.productId -> Product._id
For the relationship Component(stock) -> Product(Catalog) I've tryed
LookupOperation lookupOperation = LookupOperation.newLookup()
.from("catalog")
.localField("productId")
.foreignField("_id")
.as("product");
TypedAggregation<Component> agg =
Aggregation.newAggregation(
Component.class,
lookupOperation
);
AggregationResults<Component> results = mongoTemplate.aggregate(agg, "stock", Component.class);
return results.getMappedResults();
but it returns the whole components records without product info.
[{"_id":"5ec78573b9eb171b72f721b0","uuId":"da8800d0-b0af-4886-80d1-c384596d2261","serialNumber":"706d93ef-abf5-4f08-9cbd-e7be0af1681c","bareCode":"90168.94737714577","productId":"5ec7856eb9eb171b72f721a9","created":"2020-05-22T07:55:31.66","updated":null}, .....]
thanks for your help.
Note: In addition to @Valijon answer to be able to get the result as expected the returned object must include a "product" property either nothing is returned (using JSON REST service for example)
public class ComponentExpanded implements Serializable {
private String product;
....
with
AggregationResults<ComponentExpanded> results =
mongoTemplate.aggregate(agg,mongoTemplate.getCollectionName(Component.class), ComponentExpanded.class);