【问题标题】:How to use MongoDB $let with Spring-Data?如何将 MongoDB $let 与 Spring-Data 一起使用?
【发布时间】:2016-07-12 11:59:38
【问题描述】:

我有一个 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
    }
]
}

我想进行查询,其中排序将基于某些表达式和条件的结果的分数。从 mongo shell 我试过这个:

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

这是我的查询的一个简单示例。分数将包含更复杂的表达式,例如与某个位置的距离。问题是我找不到在 Spring 的 Java 代码中使用 $let 和 $cond 运算符的方法。有人可以帮忙吗?

【问题讨论】:

    标签: java spring mongodb spring-data aggregation-framework


    【解决方案1】:

    您应该能够使用嵌套的 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}}
    

    然后你可以添加你的其他阶段:

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

    【讨论】:

      猜你喜欢
      • 2017-01-13
      • 1970-01-01
      • 2014-10-21
      • 2017-11-07
      • 1970-01-01
      • 2017-02-02
      • 2012-05-10
      • 1970-01-01
      • 2019-03-05
      相关资源
      最近更新 更多