Not every "new" feature makes it immediately into abstraction layers such as spring-mongo.
So instead, all you need do is define a class that uses the AggregationOperation
interface, which will instead take a BSON Object specified directly as it's content:
public class CustomAggregationOperation implements AggregationOperation {
private DBObject operation;
public CustomAggregationOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
Then you can use in your aggregation like this:
Aggregation aggregation = newAggregation(
match(
Criteria.where("username").is("user001")
),
new CustomAggregationOperation(
new BasicDBObject(
"$lookup",
new BasicDBObject("from", "NewFeedContent")
.append("localField","content.contentId")
.append("foreignField", "_id")
.append("as", "NewFeedContent")
)
)
)
Which shows the custom class mixed with the built in match()
pipeline helper.
All that happens underneath each helper is that they serialize to a BSON representation such as with DBObject
anyway. So the constructor here just takes the object directly, and returns it directly from .toDBObject()
, which is the standard method on the interface that will be called when serializing the pipline contents.
Here is an example:
Collection posts
{
"_id" : ObjectId("5a198074ed31adaf5d79fe8a"),
"title" : "Post 1",
"authors" : [1, 2]
},
{
"_id" : ObjectId("5a198074ed31adaf5d79fe8d"),
"title" : "Post 2",
"authors" : [2]
}
Collection users
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed82"),
"userId" : 1,
"name" : "Vinod Kumar"
},
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed83"),
"userId" : 2,
"name" : "Jim Hazel"
},
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed84"),
"userId" : 3,
"name" : "Alex Wong"
}
Mongodb query with lookup and match
db.users.aggregate([
{
$lookup:
{
from: "users",
localField: "userid",
foreignField: "authors",
as: "post"
}
},
{
$match: { "post": { $ne: [] } }
}
]).pretty()
Spring Mongoopration syntax
LookupOperation lookupOperation = LookupOperation.newLookup().
from("posts").
localField("userid").
foreignField("authors").
as("post");
AggregationOperation match = Aggregation.match(Criteria.where("post").size(1));
Aggregation aggregation = Aggregation.newAggregation(lookupOperation, match);
List<BasicDBObject> results = mongoOperation.aggregate(aggregation, "users", BasicDBObject.class).getM