개발 꿀팁/PHP

mongodb 위치 찾기

Jammie 2022. 8. 24. 11:20
반응형

LBS는 지점별 경위도 좌표를 저장해 인근 지점을 탐색하고 지리적인 인덱스를 만들어 검색 효율을 높인다.

mongodb 지리 인덱스, 2d 및 2dsphere, 평면과 구면에 대응한다.



1.lbs 컬렉션 저장 장소 좌표 만들기

use lbs;

db.lbs.insert(
    {
        loc:{
            type: "Point",
            coordinates: [113.332264, 23.156206]
        },
        name: "광저우둥 역"
    }
)

db.lbs.insert(
    {
        loc:{
            type: "Point",
            coordinates: [113.330611, 23.147234]
        },
        name: "린허시"
    }
)

db.lbs.insert(
    {
        loc:{
            type: "Point",
            coordinates: [113.328095, 23.165376]
        },
        name: "천칭가"
    }
)

2.지리적 색인 작성

db.lbs.ensureIndex(
    {
        loc: "2dsphere"
    }
)

3.근방의 좌표를 조회하다
현재 위치: 타임스퀘어,

좌표:113.323568, 23.146436



부근의 1킬로미터 이내의 점을 찾다, 가까이에서 멀리까지 정렬하기

db.lbs.find(
    {
        loc: {
            $near:{
                $geometry:{
                    type: "Point",
                    coordinates: [113.323568, 23.146436]
                },
                $maxDistance: 1000
            }
        }
    }
)

검색 결과:

{ "_id" : ObjectId("556a651996f1ac2add8928fa"), "loc" : { "type" : "Point", "coordinates" : [ 113.330611, 23.147234 ] }, "name" : "린허시" }

php 코드는 다음과 같다

<?php
// mongodb 연결
function conn($dbhost, $dbname, $dbuser, $dbpasswd){
    $server = 'mongodb://'.$dbuser.':'.$dbpasswd.'@'.$dbhost.'/'.$dbname;
    try{
        $conn = new MongoClient($server);
        $db = $conn->selectDB($dbname);
    } catch (MongoException $e){
        throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);
    }
    return $db;
}
 
// mongodb에 좌표 삽입
function add($dbconn, $tablename, $longitude, $latitude, $name){
    $index = array('loc'=>'2dsphere');
    $data = array(
            'loc' => array(
                    'type' => 'Point',
                    'coordinates' => array(doubleval($longitude), doubleval($latitude))
            ),
            'name' => $name
    );
    $coll = $dbconn->selectCollection($tablename);
    $coll->ensureIndex($index);
    $result = $coll->insert($data, array('w' => true));
    return (isset($result['ok']) && !empty($result['ok'])) ? true : false;
}
 
// 부근의 좌표 찾기
function query($dbconn, $tablename, $longitude, $latitude, $maxdistance, $limit=10){
    $param = array(
        'loc' => array(
            '$nearSphere' => array(
                '$geometry' => array(
                    'type' => 'Point',
                    'coordinates' => array(doubleval($longitude), doubleval($latitude)), 
                ),
                '$maxDistance' => $maxdistance*1000
            )
        )
    );
 
    $coll = $dbconn->selectCollection($tablename);
    $cursor = $coll->find($param);
    $cursor = $cursor->limit($limit);
    
    $result = array();
    foreach($cursor as $v){
        $result[] = $v;
    }  
 
    return $result;
}
 
$db = conn('localhost','lbs','root','123456');
 
// 무작위로 100개의 좌표 기록을 삽입하다
for($i=0; $i<100; $i++){
    $longitude = '113.3'.mt_rand(10000, 99999);
    $latitude = '23.15'.mt_rand(1000, 9999);
    $name = 'name'.mt_rand(10000,99999);
    add($db, 'lbs', $longitude, $latitude, $name);
}
 
// 1킬로미터 이내의 점을 찾다
$longitude = 113.323568;
$latitude = 23.146436;
$maxdistance = 1;
$result = query($db, 'lbs', $longitude, $latitude, $maxdistance);
print_r($result);
?>

php 코드를 시연하려면 먼저 mongodb의 lbs에서 사용자를 만들고 auth를 실행해야 한다.방법은 다음과 같습니다

use lbs;
db.createUser(
    {
        "user":"root",
        "pwd":"123456",
        "roles":[]
    }
)

db.auth(
    {
        "user":"root",
        "pwd":"123456"
    }
)
반응형