PHP使用MongoDB存储经纬度,查询距离

Wesley13
• 阅读 220

https://blog.csdn.net/qq_40012295/article/details/84861466

https://docs.mongodb.com/manual/reference/command/geoNear/index.html

https://juejin.im/entry/5b7cfe296fb9a019d80a8ed8

<?php

/*
使用命令创建数据库:
use user

使用命令创建集合:
db.createCollection(user)

使用命令创建2dsphere索引:
db.user.createIndex({location: "2dsphere"})
*/

//PHP代码插入经纬度数据:
function uploadMongoDBLocation()
{
    $document = [
        'name' => '张三',
        'location' => [
            (float)115.036545,
            (float)36.313916,
        ],
    ];
    $manager = new \MongoDB\Driver\Manager('mongodb://127.0.0.1:27017');
    $bulk = new \MongoDB\Driver\BulkWrite;
    $bulk->insert($document); // 可连续使用多个insert
    $writeConcern = new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000);
    $res = $manager->executeBulkWrite('user.user', $bulk, $writeConcern);
    return $res;
}

//PHP代码查询距离:
//注意:这里使用的command根据版本不同,用法可能会有区别,这里使用的MongoDB版本是3.6.5
function findMongoDBLocation()
{
    $document = [
        'geoNear' => 'user',
        'near' => [
            'type' => 'Point',
            'coordinates' => [(float)'115.042725', (float)'36.312956'],
        ],
        'spherical' => true,
        'minDistance' => 0,
        'maxDistance' => 100000,
        'num' => 1000
    ];
    $command = new \MongoDB\Driver\Command($document);
    $manager = new \MongoDB\Driver\Manager('mongodb://127.0.0.1:27017');
    $cursor = $manager->executeCommand('user', $command);
    $items = [];
    foreach ($cursor as $document) {
        $total = count($document->results);
        if ($total > 0) {
            foreach ($document->results as $result) {
                $item = json_decode(json_encode($result->obj), true);
                $item['distance'] = intval($result->dis);
                unset($item['_id']);
                $items[] = $item;
            }
        }
    }
    return $items;
}

https://zhuanlan.zhihu.com/p/51839804

MongoDB实现附近的人

往数据库中批量插入数据,use mage切换到mage数据库,执行db.user.insertMany(),user是文档名,insertMany()是批量插入命令,里面传入json数组,{'name':'杨帅哥', 'address':'江西省南昌市青山湖区市场和质量监督管理局', 'gender':1, loc:[115.993121,28.676436]}代表一条用户数据,其中gender:0代表女1,代表男,loc是一个经纬度的数组,当然也可以是loc : { lng : 115.993067 , lat : 28.67606 },但官方推荐数组。

db.user.insertMany([
 {'name':'杨帅哥', 'address':'江西省南昌市青山湖区市场和质量监督管理局', 'gender':1, loc:[115.993121,28.676436]},
 {'name':'王美眉', 'address':'江西省南昌市青山湖区创新一路职位小厨', 'gender':0, loc:[116.000093,28.679402]},
 {'name':'张美眉', 'address':'江西省南昌市青山湖区紫阳大道1916号', 'gender':0, loc:[115.999967,28.679743]},
 {'name':'李美眉', 'address':'江西省南昌市青山湖区云中城', 'gender':0, loc:[115.995593,28.681632]},
 {'name':'彭美眉', 'address':'江西省南昌市青山湖区北京东路1666号', 'gender':0, loc:[115.975543,28.679509]},
 {'name':'赵美眉', 'address':'江西省南昌市青山湖区市场一路大润发', 'gender':0, loc:[115.968428,28.669368]},
 {'name':'廖美眉', 'address':'江西省南昌市南昌县奥林匹克中心', 'gender':0, loc:[116.035262,28.677037]},
 {'name':'余帅哥', 'address':'江西省南昌市南昌县科技学院瑶湖校区', 'gender':1, loc:[116.02477,28.68667]},
 {'name':'吴帅哥', 'address':'江西省南昌市青山湖区创新一路母婴店', 'gender':1, loc:[116.002384,28.683865]},
 {'name':'何帅哥', 'address':'江西省南昌市青山湖区紫阳大道2999号', 'gender':1, loc:[116.000821,28.68129]},
])

设置2d索引

因为我以二维平面上点的方式存储的数据,想要进行LBS查询,那么要设置2d索引。db.user.createIndex({'loc':"2d"})其中loc是索引的字段。

PHP使用MongoDB存储经纬度,查询距离

六、查询附近200米的人

查询附近的人,首先的指导当前用户所在的经纬度,如果不仅想要得到数据还要得到距离,那么可以使用$geoNear指令,如果距离自己去计算可以使用$near或者$geoWithin然后在手动计算距离。此处采用$geoNear指令查询附近2000m的人。

db.user.aggregate({
    $geoNear:{
        near: [115.999567,28.681813], // 当前坐标
        spherical: true, // 计算球面距离
        distanceMultiplier: 6378137, // 地球半径,单位是米,那么的除的记录也是米
        maxDistance: 2000/6378137, // 过滤条件2000米内,需要弧度
        distanceField: "distance" // 距离字段别名
    }
})

public function CI_mongodb($data)
    {
        //near: [115.999567,28.681813], // 当前坐标
        //spherical: true, // 计算球面距离
        //distanceMultiplier: 6378137, // 地球半径,单位是米,那么的除的记录也是米
        //maxDistance: 400/6378137, // 过滤条件2000米内,需要弧度
        //distanceField: "distance" // 距离字段别名

        $document = [
            'geoNear' => 'user',
            'near' => [(float)'115.999567', (float)'28.681813'],
            'spherical' => true,
            'distanceMultiplier' => 6378137,
            'maxDistance' => 400 / 6378137,
            'num' => 2,
        ];
        $res = $this>CI>lib_mongodb>command($document);
        PE($res);
    
    }
点赞
收藏
评论区
推荐文章
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
光头强的博客 光头强的博客
5个月前
Java面向对象试题
1、请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
刚刚好 刚刚好
5个月前
css问题
1、在IOS中图片不显示(给图片加了圆角或者img没有父级)<div<imgsrc""/</divdiv{width:20px;height:20px;borderradius:20px;overflow:h
小森森 小森森
5个月前
校园表白墙微信小程序V1.0 SayLove -基于微信云开发-一键快速搭建,开箱即用
后续会继续更新,敬请期待2.0全新版本欢迎添加左边的微信一起探讨!项目地址:(https://www.aliyun.com/activity/daily/bestoffer?userCodesskuuw5n)\2.Bug修复更新日历2.情侣脸功能大家不要使用了,现在阿里云的接口已经要收费了(土豪请随意),\\和注意
晴空闲云 晴空闲云
5个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
Wesley13 Wesley13
1年前
Java爬虫之JSoup使用教程
title:Java爬虫之JSoup使用教程date:201812248:00:000800update:201812248:00:000800author:mecover:https://imgblog.csdnimg.cn/20181224144920712(https://www.oschin
Wesley13 Wesley13
1年前
MySQL查询按照指定规则排序
1.按照指定(单个)字段排序selectfromtable_nameorderiddesc;2.按照指定(多个)字段排序selectfromtable_nameorderiddesc,statusdesc;3.按照指定字段和规则排序selec
Stella981 Stella981
1年前
Angular material mat
IconIconNamematiconcode_add\_comment_addcommenticon<maticonadd\_comment</maticon_attach\_file_attachfileicon<maticonattach\_file</maticon_attach\
Wesley13 Wesley13
1年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
helloworld_34035044 helloworld_34035044
8个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为