基本介绍

位置服务(LBS)解决的主要问题是当前位置周围某个范围内的人或场所.

在传统的解决方案,开发人员需要根据复杂的几何运算与大量的SQL语句进行查找,这无疑加大的开发人员的开发难度.

现在我们需要更为方便的解决方案,MongoDB为我们完美解决此类LBS问题.此篇文章也主要使用SpringData,将spring与MongoDB进行整合.

二维地图

MongoDB目前支持二维的地图查询,查询区域包括圆形与矩形,距离单位包括MILES,KILOMETERS,NEUTRAL,下面的示例演示距离单位为NEUTRAL,而实际生产应用中则会用到MILES与KILOMETERS.

MongoDB示例

首先定义一个位置集合,给定a,b,c,d节点.

1

2

3

4

5

6

7

8

>

db

.

createCollection

(

"location"

)

{

"ok"

:

1

}

>

db

.

location

.

save

(

{

_id

:

"A"

,

position

:

[

0.1

,

-

0.1

]

}

)

>

db

.

location

.

save

(

{

_id

:

"B"

,

position

:

[

1.0

,

1.0

]

}

)

>

db

.

location

.

save

(

{

_id

:

"C"

,

position

:

[

0.5

,

0.5

]

}

)

>

db

.

location

.

save

(

{

_id

:

"D"

,

position

:

[

-

0.5

,

-

0.5

]

}

)

接着指定location索引

1

db

.

location

.

ensureIndex

(

{

position

:

"2d"

}

)

现在我们可以进行简单的GEO查询

查询point(0,0),半径0.7附近的点

1

2

3

4

>

db

.

location

.

find

(

{

position

:

{

$near

:

[

0

,

0

]

,

$maxDistance

:

0.7

}

}

)

{

"_id"

:

"A"

,

"position"

:

[

0.1

,

-

0.1

]

}

查询point(0,0),半径0.75附近的点

1

2

3

4

5

6

>

db

.

location

.

find

(

{

position

:

{

$near

:

[

0

,

0

]

,

$maxDistance

:

0.75

}

}

)

{

"_id"

:

"A"

,

"position"

:

[

0.1

,

-

0.1

]

}

{

"_id"

:

"C"

,

"position"

:

[

0.5

,

0.5

]

}

{

"_id"

:

"D"

,

"position"

:

[

-

0.5

,

-

0.5

]

}

我们可以看到半径不一样,查询出的点也不一样,因为c点坐标为[0.5,0.5],c至圆点的距离根据勾股定理可得出Math.sqrt(0.25 +0.25) ≈ 0.707,所以最大距离0.7时查找不到你要的点.

查询[0.25, 0.25], [1.0,1.0]区域附近的点

1

2

3

4

5

>

db

.

location

.

find

(

{

position

:

{

$within

:

{

$box

:

[

[

0.25

,

0.25

]

,

[

1.0

,

1.0

]

]

}

}

}

)

{

"_id"

:

"C"

,

"position"

:

[

0.5

,

0.5

]

}

{

"_id"

:

"B"

,

"position"

:

[

1

,

1

]

}

Spring Data示例

spring data为我们封装了mongoDB访问接口与实现,我们可以像使用hibernateTemplate一样使用mongoTemplate.

首先我们需要像hibernate一样定义pojo类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

import

org

.

springframework

.

data

.

annotation

.

Id

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

mapping

.

Document

;

@Document

(

collection

=

"location"

)

public

class

Location

{

@Id

private

String

id

;

private

double

[

]

position

;

/** getter setter hashcode equals toString ...  */

}

定义Dao,我们先使用最简单的mongoTemplate来实现

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

import

java

.

util

.

List

;

import

org

.

springframework

.

beans

.

factory

.

annotation

.

Autowired

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

MongoTemplate

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

geo

.

Box

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

geo

.

Point

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

query

.

Criteria

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

query

.

Query

;

import

org

.

springframework

.

stereotype

.

Repository

;

@Repository

public

class

LocationDao

{

@Autowired

MongoTemplate

mongoTemplate

;

public

List

findCircleNear

(

Point

point

,

double

maxDistance

)

{

return

mongoTemplate

.

find

(

new

Query

(

Criteria

.

where

(

"position"

)

.

near

(

point

)

.

maxDistance

(

maxDistance

)

)

,

Location

.

class

)

;

}

public

List

findBoxNear

(

Point

lowerLeft

,

Point

upperRight

)

{

return

mongoTemplate

.

find

(

new

Query

(

Criteria

.

where

(

"position"

)

.

within

(

new

Box

(

lowerLeft

,

upperRight

)

)

)

,

Location

.

class

)

;

}

}

最后我们写一个test类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

import

java

.

util

.

Collection

;

import

java

.

util

.

List

;

import

org

.

junit

.

Before

;

import

org

.

junit

.

Test

;

import

org

.

junit

.

runner

.

RunWith

;

import

org

.

springframework

.

beans

.

factory

.

annotation

.

Autowired

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

MongoTemplate

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

geo

.

Point

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

index

.

GeospatialIndex

;

import

org

.

springframework

.

test

.

context

.

ContextConfiguration

;

import

org

.

springframework

.

test

.

context

.

junit4

.

SpringJUnit4ClassRunner

;

@RunWith

(

SpringJUnit4ClassRunner

.

class

)

@ContextConfiguration

(

locations

=

{

"classpath:/applicationContext.xml"

,

"classpath:/application-mongo.xml"

}

)

public

class

MongoDBTest

{

@Autowired

LocationDao

locationDao

;

@Autowired

MongoTemplate

template

;

@Before

public

void

setUp

(

)

{

// 等同db.location.ensureIndex( {position: "2d"} )

template

.

indexOps

(

Location

.

class

)

.

ensureIndex

(

new

GeospatialIndex

(

"position"

)

)

;

// 初始化数据

template

.

save

(

new

Location

(

"A"

,

0.1

,

-

0.1

)

)

;

template

.

save

(

new

Location

(

"B"

,

1

,

1

)

)

;

template

.

save

(

new

Location

(

"C"

,

0.5

,

0.5

)

)

;

template

.

save

(

new

Location

(

"D"

,

-

0.5

,

-

0.5

)

)

;

}

@Test

public

void

findCircleNearTest

(

)

{

List

locations

=

locationDao

.

findCircleNear

(

new

Point

(

0

,

0

)

,

0.7

)

;

print

(

locations

)

;

System

.

err

.

println

(

"-----------------------"

)

;

locations

=

locationDao

.

findCircleNear

(

new

Point

(

0

,

0

)

,

0.75

)

;

print

(

locations

)

;

}

@Test

public

void

findBoxNearTest

(

)

{

List

locations

=

locationDao

.

findBoxNear

(

new

Point

(

0.2

,

0.2

)

,

new

Point

(

1

,

1

)

)

;

print

(

locations

)

;

}

public

static

void

print

(

Collection

locations

)

{

for

(

Location

location

:

locations

)

{

System

.

err

.

println

(

location

)

;

}

}

}

大家可以看到运行结果与我们直接在mongoDB上的一样.

MongoRepository

MongoRepository提供了对MongoTemplate的封装与实现,只需要继承MongoRepository接口,填上对应的bean类与ID类型,无需实现里面的方法即可使用,先看代码.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

import

org

.

springframework

.

data

.

mongodb

.

core

.

geo

.

Box

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

geo

.

Distance

;

import

org

.

springframework

.

data

.

mongodb

.

core

.

geo

.

Point

;

import

org

.

springframework

.

data

.

mongodb

.

repository

.

MongoRepository

;

public

interface

LocationRepository

extends

MongoRepository

<

Location

,

String

>

{

List

findByPositionNear

(

Point

p

,

Distance

d

)

;

List

findByPositionWithin

(

Box

b

)

;

}

然后在test类中引用此类即可,MongoRepository实现了最基本的增删改查的功能,要想增加额外的查询方法,可以按照以下规则定义接口的方法.

自定义查询方法,格式为findBy+字段名+方法名,方法传进的参数即字段的值,此外还支持分页查询,通过传进一个Pageable对象会返回Page集合.

原理相信大家也很清楚,即aop,细节就不说拉.

小提示

near与within方法区别,near方法查询后会对结果集对distance进行排序且有大小限制,而within是无序的也无大小限制.

如果大家有新发现,也可回帖,我会及时补充.

mongodb lbs java_LBS JAVA Spring mongoDB相关推荐

  1. 云栖社区特邀专家徐雷——Java Spring Boot开发实战系列课程【往期直播回顾】...

    徐雷,花名:徐雷frank:资深架构师,MongoDB中文社区联席主席,吉林大学计算机学士,上海交通大学硕士.从事了 10年+开发工作,专注于分布式架构,Java Spring Boot.Spring ...

  2. Spring+mongodb集群集成(吐血教程) 转自:http://blog.csdn.net/qq_16497617/article/details/52817335

    前一篇文章中介绍了在window系统下部署mongodb集群,按照教程一步步实现的话应该都可以在本机部署成功了,上篇文章末尾也提到了,想集成到SSM框架中去,网上资料基本都是单个mongodb数据库的 ...

  3. Spring整合Mongodb,Maven的依赖,Spring配置,MongoDB的公共操作类,使用SpringMVC的Controller进行测试并返回结果的案例

    在和Spring和MongoDB进行整合的时候需要如下三个jar,分别是: spring-data-commons spring-data-mongodb mongo-java-driver 下面讲解 ...

  4. 大数据之mongodb -- (2)java集成 MongoDB 3.2,使用Spring-data-mongodb进行集成

    Java集成MongoDB有很多方式,可以直接用mongodb的java驱动程序来发送语句到mongodb服务器,也可以用第三方的工具包来做. (1) 选择版本 选择的就是springdata集成的m ...

  5. Java EE + MongoDb与Apache TomEE和Jongo Starter项目

    知道MongoDB和Java EE ,但是您不知道如何将两者集成在一起? 您是否阅读了很多有关该主题的内容,但没有找到适合该目的的解决方案? 这个入门项目适合您: 您将学习如何以一种时尚的方式使用Mo ...

  6. java 连接mongodb

    java mongo 驱动API   http://mongodb.github.io/mongo-java-driver/ maven中添加依赖 http://mongodb.github.io/m ...

  7. Spring MongoDB查询附近的人功能实现

    Spring MongoDB简易实现查询附近的人功能 文章目录 1.准备 2.搭建基础结构并编写代码 3.测试接口 1.分别存入3位用户 2.测试使用id查用户 3.使用广东博物馆西门的坐标测试附近有 ...

  8. Java操作Mongodb数据(增删改查聚合查询)

    文章目录 一.Java操作MongoDB 二.使用步骤 1.基础配置 2.实体类 3.MongoDB表数据 3.增删改查聚合查询 总结 一.Java操作MongoDB 上一篇文章介绍了,如何在本地使用 ...

  9. Java操作MongoDB详解

    Java操作MongoDB详解 1. MongoDB概述 1.1 MongoDB简介 1.2 MongoDB概念 2. MongoDB安装 2.1 MongoDB下载 2.2 MongoDB安装 2. ...

最新文章

  1. 让我们山寨一张Windows Azure Global的壁纸
  2. Typora开始收费,介绍几款免费的MarkDown编辑器
  3. 前端工程师应该达到什么水平,找工作薪资才比较高?
  4. leetcode39. 组合总和(回溯)
  5. mvc ajax post json数据,springmvc解决ajax post json格式数据的跨域问题
  6. 如何在GPT分区上安装WIN7
  7. 下载python流程-Python编写win程序的操作流程
  8. C++实现数组类模板
  9. C#基础笔记(第十天)
  10. 软件开发中 前台、中台、后台英文_中台为什么这么火?
  11. 【图像修复】基于matlab GUI中值+均值+维纳+最小平方图像恢复【含Matlab源码 838期】
  12. 微信公众号网页授权流程
  13. 用计算机弹生僻字乐谱,生僻字 E调(拇指琴卡林巴琴弹奏谱)
  14. 智能语音助手的时代,我们还有这样的一股清流:114!
  15. 30天自制操作系统 第一天
  16. 无线射频专题《射频合规,2.4GHz WIFI频谱模板》
  17. 物联网行业解决方案之智慧畜牧
  18. 网易im即时聊天php怎么接入,网易云信IM即时通讯功能接入方式与流程_如何收费_企业服务汇...
  19. vim autoformat php,vim - 如何在VI中整理HTML文件的缩进?
  20. 超级玛丽3号MAX 达尔文3号,谁才是真正的重疾险王炸?

热门文章

  1. python easygui_python简单图形界面GUI入门——easygui
  2. Eigen(4)矩阵基本运算
  3. c++可以做什么项目_上班做下班后可以做的兼职项目
  4. 补码原理一个字节存储数值的范围如何计算
  5. mysql group by 重复_mysql – 使用GROUP BY删除重复项的查询
  6. shell 删除七日内日志_shell日志删除(超容量自动)
  7. 计算机组成原理实验三报告,计算机组成原理实验三报告
  8. php连接mysql_PHP连接MySQL数据库的三种方式
  9. 作为服务器上的操作系统,作为服务器的操作系统
  10. 为Kindeditor控件添加图片自动上传功能