有什么做照片书的网站,中国企业500强净利润排名,淄博做网站市场,中文域名网站好不好优化基本介绍位置服务(LBS)解决的主要问题是当前位置周围某个范围内的人或场所.在传统的解决方案,开发人员需要根据复杂的几何运算与大量的SQL语句进行查找,这无疑加大的开发人员的开发难度.现在我们需要更为方便的解决方案,MongoDB为我们完美解决此类LBS问题.此篇文章也主要使用Sp…基本介绍位置服务(LBS)解决的主要问题是当前位置周围某个范围内的人或场所.在传统的解决方案,开发人员需要根据复杂的几何运算与大量的SQL语句进行查找,这无疑加大的开发人员的开发难度.现在我们需要更为方便的解决方案,MongoDB为我们完美解决此类LBS问题.此篇文章也主要使用SpringData,将spring与MongoDB进行整合.二维地图MongoDB目前支持二维的地图查询,查询区域包括圆形与矩形,距离单位包括MILES,KILOMETERS,NEUTRAL,下面的示例演示距离单位为NEUTRAL,而实际生产应用中则会用到MILES与KILOMETERS.MongoDB示例首先定义一个位置集合,给定a,b,c,d节点.12345678db.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索引1db.location.ensureIndex({position:2d})现在我们可以进行简单的GEO查询查询point(0,0),半径0.7附近的点1234db.location.find({position:{$near:[0,0],$maxDistance:0.7}}){_id:A,position:[0.1,-0.1]}查询point(0,0),半径0.75附近的点123456db.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]区域附近的点12345db.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类12345678910111213141516importorg.springframework.data.annotation.Id;importorg.springframework.data.mongodb.core.mapping.Document;Document(collectionlocation)publicclassLocation{IdprivateStringid;privatedouble[]position;/** getter setter hashcode equals toString ... */}定义Dao,我们先使用最简单的mongoTemplate来实现12345678910111213141516171819202122232425262728293031importjava.util.List;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.mongodb.core.MongoTemplate;importorg.springframework.data.mongodb.core.geo.Box;importorg.springframework.data.mongodb.core.geo.Point;importorg.springframework.data.mongodb.core.query.Criteria;importorg.springframework.data.mongodb.core.query.Query;importorg.springframework.stereotype.Repository;RepositorypublicclassLocationDao{AutowiredMongoTemplatemongoTemplate;publicListfindCircleNear(Pointpoint,doublemaxDistance){returnmongoTemplate.find(newQuery(Criteria.where(position).near(point).maxDistance(maxDistance)),Location.class);}publicListfindBoxNear(PointlowerLeft,PointupperRight){returnmongoTemplate.find(newQuery(Criteria.where(position).within(newBox(lowerLeft,upperRight))),Location.class);}}最后我们写一个test类1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859importjava.util.Collection;importjava.util.List;importorg.junit.Before;importorg.junit.Test;importorg.junit.runner.RunWith;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.mongodb.core.MongoTemplate;importorg.springframework.data.mongodb.core.geo.Point;importorg.springframework.data.mongodb.core.index.GeospatialIndex;importorg.springframework.test.context.ContextConfiguration;importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner;RunWith(SpringJUnit4ClassRunner.class)ContextConfiguration(locations{classpath:/applicationContext.xml,classpath:/application-mongo.xml})publicclassMongoDBTest{AutowiredLocationDaolocationDao;AutowiredMongoTemplatetemplate;BeforepublicvoidsetUp(){// 等同db.location.ensureIndex( {position: 2d} )template.indexOps(Location.class).ensureIndex(newGeospatialIndex(position));// 初始化数据template.save(newLocation(A,0.1,-0.1));template.save(newLocation(B,1,1));template.save(newLocation(C,0.5,0.5));template.save(newLocation(D,-0.5,-0.5));}TestpublicvoidfindCircleNearTest(){ListlocationslocationDao.findCircleNear(newPoint(0,0),0.7);print(locations);System.err.println(-----------------------);locationslocationDao.findCircleNear(newPoint(0,0),0.75);print(locations);}TestpublicvoidfindBoxNearTest(){ListlocationslocationDao.findBoxNear(newPoint(0.2,0.2),newPoint(1,1));print(locations);}publicstaticvoidprint(Collectionlocations){for(Locationlocation:locations){System.err.println(location);}}}大家可以看到运行结果与我们直接在mongoDB上的一样.MongoRepositoryMongoRepository提供了对MongoTemplate的封装与实现,只需要继承MongoRepository接口,填上对应的bean类与ID类型,无需实现里面的方法即可使用,先看代码.1234567891011121314importorg.springframework.data.mongodb.core.geo.Box;importorg.springframework.data.mongodb.core.geo.Distance;importorg.springframework.data.mongodb.core.geo.Point;importorg.springframework.data.mongodb.repository.MongoRepository;publicinterfaceLocationRepositoryextendsMongoRepositoryLocation,String{ListfindByPositionNear(Pointp,Distanced);ListfindByPositionWithin(Boxb);}然后在test类中引用此类即可,MongoRepository实现了最基本的增删改查的功能,要想增加额外的查询方法,可以按照以下规则定义接口的方法.自定义查询方法,格式为findBy字段名方法名,方法传进的参数即字段的值,此外还支持分页查询,通过传进一个Pageable对象会返回Page集合.原理相信大家也很清楚,即aop,细节就不说拉.小提示near与within方法区别,near方法查询后会对结果集对distance进行排序且有大小限制,而within是无序的也无大小限制.如果大家有新发现,也可回帖,我会及时补充.