2016-07-12 4 views
0

У меня есть коллекция мест MongoDB. Типичное место имеет большинство из следующих полей:

{ 
"_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 
    } 
] 
} 

Я хочу, чтобы делать запросы, где сортировка будет основываться на счете, который является результатом некоторых выражений и условий. Из оболочки монго я пробовал это:

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(); 

Это простой пример моих запросов. Оценка будет содержать более сложные выражения, такие как расстояние от места. Проблема в том, что я не могу найти способ использовать оператор $ let и $ cond в своем Java-коде с Spring. Может ли кто-нибудь помочь?

ответ

0

Вы должны быть в состоянии сделать это, используя вложенный DBObject и пользовательскую операцию агрегирования.

Для примера:

Map operations = new HashMap(); 
operations.put("name", 1); 
operations.put("location", 1); 
operations.put("score", new BasicDBObject("$let", new BasicDBObject("vars", new BasicDBObject()))); 

Затем вы можете создать CustomAggregationOperation, чтобы добавить это к вашему проекту

CustomAggregationOperation project = new CustomAggregationOperation(new BasicDBObject("$project", operation)); 

Это даст вам следующий трубопровод:

{ "$project" : { "score" : { "$let" : { "vars" : { }}} , "name" : 1 , "location" : 1}} 

Затем вы можете добавить свой другой sta о.э.р.:

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); 
    } 
} 
Смежные вопросы