mongoDB查询某个经纬度附近的用户

来源:互联网 发布:C语言网络地址访问 编辑:程序博客网 时间:2024/04/30 09:36

需求:获取某个点100m内的用户
数据库:mongoDB
语言:JAVA
1.地理位置数据以GeoJSON 的格式存储的

loc : {    type : "Point",    coordinates : [lng, lat]}

查询地理位置用到geoWithincenterSphere, 查询语句为

{   location field: {      $geoWithin: { $centerSphere: [ [ x, y ], radius] }   }}

x,y为中心点的经纬度,radius为距离中心点的距离,$centerSphere 使用弧度(radians)作为距离
距离与弧度之间的转换:
distance to radians: divide the distance by the radius of the sphere (e.g. the Earth) in the same units as the distance measurement.
radians to distance: multiply the radian measure by the radius of the sphere (e.g. the Earth) in the units system that you want to convert the distance to.
地球赤道的半径为3963.2 miles, 即 6378.1 kilometers, 只查找100m范围内,则radius为100/6378100。
参考信息:
geowithin
centerSphere
calculate distances

Coordinates中数据类似如下:

{    "_id" : ObjectId("58403433785509513efe3279"),    "account" : "18520222222",    "platform" : "android",    "location" : {        "type" : "Point",        "coordinates" : [             108.840974298098,             34.2789316522934        ]    },        "collectTime" : 1480602671,    "logTime" : 1480602675}

JAVA代码,此处只写了unit test, 简单测试代码逻辑。实际使用需要做相应改动。

package mongo;import java.net.UnknownHostException;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import org.bson.Document;import org.junit.Before;import org.junit.Test;import com.mongodb.BasicDBList;import com.mongodb.BasicDBObject;import com.mongodb.MongoClient;import com.mongodb.MongoClientOptions;import com.mongodb.MongoCredential;import com.mongodb.MongoException;import com.mongodb.ServerAddress;import com.mongodb.client.MongoCursor;import com.mongodb.client.MongoDatabase;public class CoordinatesTest {    public static final String mgoHost = "127.0.0.1:27017";    public static final String mgoUser = "test";    public static final String mgoPwd = "123456";    public static final String mgoDB = "info";      private static MongoDatabase db = null;         @SuppressWarnings("resource")    public void initMongo() throws UnknownHostException, MongoException {        MongoClientOptions.Builder build = new MongoClientOptions.Builder();        build.connectionsPerHost(50);        build.threadsAllowedToBlockForConnectionMultiplier(50);        build.maxWaitTime(1000*60*2);        build.connectTimeout(1000*30);        build.socketTimeout(1000*30);        List<ServerAddress> seeds = new ArrayList<ServerAddress>();        seeds.add(new ServerAddress(mgoHost));        MongoCredential credentials = MongoCredential.createScramSha1Credential(mgoUser, mgoDB, mgoPwd.toCharArray());        List<MongoCredential> credentialsList = new ArrayList<MongoCredential>();        credentialsList.add(credentials);        MongoClient mongoClient = new MongoClient(seeds, credentialsList, build.build());        db = mongoClient.getDatabase(mgoDB);    }    public static List<String> distinct(String coll, BasicDBObject query, String key) {                List<String> list = new ArrayList<String>();        MongoCursor<Document> cursor = null;        try {            cursor = db.getCollection(coll).find(query).projection(new BasicDBObject(key, 1)).iterator();            if (cursor != null) {                HashSet<String> set = new HashSet<String>();                while (cursor.hasNext()){                    Document doc = cursor.next();                    String val = doc.getString(key);                    if (!set.contains(val)) {                        set.add(val);                    }                }                list.addAll(set);            }        } catch (Throwable e) {            System.err.println("coll:"+coll+", query:"+query+", key:"+key+", occur exception: " + e.getMessage());        } finally {            if (cursor != null) {                cursor.close();            }        }        return list;    }    public static List<String> getAccountsByLocation(double longitude, double latitude, double radius) {        BasicDBList point = new BasicDBList();        point.add(longitude);        point.add(latitude);        Double distance = radius/6378100;        BasicDBList centerSphere = new BasicDBList();        centerSphere.add(point);        centerSphere.add(distance);        BasicDBObject location = new BasicDBObject("$geoWithin", new BasicDBObject("$centerSphere", centerSphere));        BasicDBObject query = new BasicDBObject("location", location);        List<String> list = new ArrayList<String>();        try {            list = CoordinatesTest.distinct("Coordinates", query, "account");        } catch (MongoException e) {            System.err.println(e.getMessage());        }        return list;    }    @Before    public void init() throws Exception {        initMongo();    }    @Test    public void test1() {        List<String> accountList = getAccountsByLocation(113.941892, 22.50986, 100);        System.out.println(accountList);    }}
0 0