mongodb 自定义geoNear

原因

1.使用spring分装的 Aggregation.geoNear 得不到想要的结果数据,总有偏差

1.1 量度(distance) 两点间的距离不正确
1.2 maxDistance 最大距离不生效

spring mongodb 2.1.1

1.pom文件

	<dependency>
		<groupId>org.springframework.data</groupId>
		<artifactId>spring-data-mongodb</artifactId>
		<version>2.1.1.RELEASE</version>
	</dependency>

2.spring分装好的 geoNear

	NearQuery nearQuery = NearQuery.near(point, Metrics.MILES);
    nearQuery.maxDistance(maxDistance);
    nearQuery.query(query);
    if(sort != null){
        nearQuery.with(PageRequest.of(pageNum, pageSize, sort));
    } else{
        nearQuery.with(PageRequest.of(pageNum, pageSize));
    }
    List<AggregationOperation> aggregationList = new ArrayList<>();
    aggregationList.add(Aggregation.geoNear(nearQuery, distanceField));
    if(sort != null){
        aggregationList.add(Aggregation.sort(sort));
    }
    Aggregation agg = Aggregation.newAggregation(aggregationList);

查看源码

1.spring mongodb Operation 都实现了 AggregationOperation类

public interface AggregationOperation {

/**
 * Turns the {@link AggregationOperation} into a {@link Document} by using the given
 * {@link AggregationOperationContext}.
 *
 * @return the Document
 */
Document toDocument(AggregationOperationContext context);
}

最终都调用了 toDocument方法

定义 geoNear

public class GeoNearDocument implements AggregationOperation {

    private Document nearQuery;
    /**
     * 自定义 GeoNear
     * @param query 查询条件
     * @param point 坐标
     * @param distanceField 两点之间的距离字段
     * @param maxDistance  两点之间的最大距离
     */
    public GeoNearDocument(Query query, Point point, String distanceField, double maxDistance) {
        Assert.notNull(query, "query must not be null.");
        Assert.notNull(point, "point must not be null.");
        Assert.notNull(point.getX(), "point x must not be null.");
        Assert.notNull(point.getY(), "point y must not be null.");
        Assert.notNull(distanceField, "distanceField must not be null.");
        this.nearQuery = new Document("near", new Document("type", "Point")
                .append("coordinates", new double[]{point.getX(), point.getY()}))
                .append("distanceField", distanceField)
                .append("query", query.getQueryObject())
                .append("num", 1000)
                .append("maxDistance", maxDistance)
                .append("spherical", true);
    }

    @Override
    public Document toDocument(AggregationOperationContext context) {
        Document command = context.getMappedObject(nearQuery);
        return new Document("$geoNear", command);
    }
}

使用

	List<AggregationOperation> aggregationList = new ArrayList<>();
    aggregationList.add(new GeoNearDocument(query, point, distanceField, maxDistance));
    aggregationList.add(Aggregation.skip((pageNum-1) * pageSize));
    aggregationList.add(Aggregation.limit(pageSize));
    if(sort != null){
        aggregationList.add(Aggregation.sort(sort));
    }
    Aggregation agg = Aggregation.newAggregation(
            aggregationList);
    log.info("坐标查询条件:{}", Arrays.asList(aggregationList));
    AggregationResults<T> maps = mongoTemplate.aggregate(agg, collectionName, this.getEntityClass());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值