java - How to use MongoDB $let with Spring-Data? -
i have mongodb collection of places. typical place has of following fields:
{ "_id" : objectid("575014dc6b028f07bef53681"), "_class" : "domain.model.placev1", "name" : "Γιασεμί", "primary_photo_url" : "https://irs0.4sqi.net/img/general/original/34666238_sthsh6chic7hpaub4rztrvg6cfc5ylfi15arar7zuuq.jpg", "seendetails" : numberlong(0), "foursquare_checkins" : 646, "foursquare_tips" : 28, "keywords" : [ "" ], "verified" : 1, "location" : { "loc" : { "type" : "point", "coordinates" : [ 25.898318, 36.831486 ] }, "formattedaddress" : "Χώρα", "locality" : "amorgos", "first_neighbourhood" : "katapola", "greek_locality" : "Αμοργός", "greek_first_neighbourhood" : "Κατάπολα" }, "contact" : { "phone_numbers" : [ "+30 2285 074017" ] }, "price" : { "pricevotes" : numberlong(0), "price" : 0, "pricevotessum" : numberlong(0) }, "rating" : { "rating" : 8, "ratingvotes" : numberlong(0), "ratingvotessum" : numberlong(0) }, "categories" : [ { "cat_id" : numberlong(10310061000), "category" : "café", "greek_category" : "Καφετέρια", "weight" : 4 }, { "cat_id" : numberlong(11610021000), "category" : "bar", "greek_category" : "Μπαρ", "weight" : 4 } ] }
i want make queries sorting based on score result of expressions , conditions. mongo shell have tried this:
db.place.aggregate([ {$match:{"location.locality":"athens"}}, {$project: {name:1, location:1, score:{ $let: { vars:{ foursquare: { $cond: { if: { $gte: [ "$foursquare_checkins", 500 ] }, then: 500, else: "$foursquare_checkins" } }, rating: {$multiply:["$rating.rating", 100]}, }, in:{$add:["$$foursquare", "$$rating", "$seendetails"]} } } } }, {$sort: {score: -1}}]).pretty();
this simple example of queries. score contain more complex expressions distance location. problem cannot find way use $let , $cond operator in java code spring. help?
you should able using nested dbobject
, custom aggregation operation.
for example:
map operations = new hashmap(); operations.put("name", 1); operations.put("location", 1); operations.put("score", new basicdbobject("$let", new basicdbobject("vars", new basicdbobject())));
then can create customaggregationoperation
add project
customaggregationoperation project = new customaggregationoperation(new basicdbobject("$project", operation));
this give following pipeline:
{ "$project" : { "score" : { "$let" : { "vars" : { }}} , "name" : 1 , "location" : 1}}
then can add other stages:
aggregation aggregate = aggregation.newaggregation(match, project, sort);
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); } }
Comments
Post a Comment