我正在尝试使用MongoDB的GeoSpatial功能。我有这份文件:
<?php
namespace My\CoreBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* @MongoDB\Document
* @MongoDB\Index(keys={"coordinates"="2d"})
*/
class WorkoutLocation
{
/** @MongoDB\Id */
protected $id;
/** @MongoDB\ReferenceMany(targetDocument="User") */
protected $users;
/** @MongoDB\String */
protected $name;
/** @MongoDB\EmbedOne(targetDocument="Coordinates") */
protected $coordinates;
/** @MongoDB\Distance */
protected $distance;
public function __construct()
{
$this->users = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function addUser(\My\CoreBundle\Document\User $users)
{
$this->users[] = $users;
}
public function removeUser(\My\CoreBundle\Document\User $users)
{
$this->users->removeElement($users);
}
public function getUsers()
{
return $this->users;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
/**
* Set coordinates
*
* @param My\CoreBundle\Document\Coordinates $coordinates
* @return \WorkoutLocation
*/
public function setCoordinates(\My\CoreBundle\Document\Coordinates $coordinates)
{
$this->coordinates = $coordinates;
return $this;
}
public function getCoordinates()
{
return $this->coordinates;
}
/**
* Set distance
*
* @param string $distance
* @return \WorkoutLocation
*/
public function setDistance($distance)
{
$this->distance = $distance;
return $this;
}
/**
* Get distance
*
* @return string $distance
*/
public function getDistance()
{
return $this->distance;
}
}
和坐标文件
<?php
namespace My\CoreBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/** @MongoDB\EmbeddedDocument */
class Coordinates
{
/** @MongoDB\Float */
protected $latitude;
/** @MongoDB\Float */
protected $longitude;
public function __construct($latitude = 0.0, $longitude = 0.0)
{
$this->setLatitude($latitude);
$this->setLongitude($longitude);
}
/**
* Set latitude
*
* @param float $latitude
* @return \Coordinates
*/
public function setLatitude($latitude)
{
$this->latitude = $latitude;
return $this;
}
/**
* Get latitude
*
* @return float $latitude
*/
public function getLatitude()
{
return $this->latitude;
}
/**
* Set longitude
*
* @param float $longitude
* @return \Coordinates
*/
public function setLongitude($longitude)
{
$this->longitude = $longitude;
return $this;
}
/**
* Get longitude
*
* @return float $longitude
*/
public function getLongitude()
{
return $this->longitude;
}
}
我有这个数据
/* 0 */
{
"_id" : ObjectId("517a1f45dd1854c818000001"),
"name" : "ABC Gym Master",
"coordinates" : {
"latitude" : -8.711741,
"longitude" : 115.166538
}
}
/* 1 */
{
"_id" : ObjectId("517a1f45dd1854c818000002"),
"name" : "DEF Master Gym",
"coordinates" : {
"latitude" : -8.712292,
"longitude" : 115.16694
}
}
/* 2 */
{
"_id" : ObjectId("517a1f45dd1854c818000003"),
"name" : "GHI Master Gym",
"coordinates" : {
"latitude" : -8.68808,
"longitude" : 115.1718
}
}
查看:
{% for location in locations %}
Name: {{ location.name }}, Distance: {{ location.distance }}
{% endfor %}
但是当我尝试这段代码时:
$dm = $this->get('doctrine_mongodb')->getManager();
$locations = $dm->createQueryBuilder('MyCoreBundle:WorkoutLocation')
->field('coordinates')->near(-8.688038,115.171329)
->getQuery()
->execute();
return $this->render('MyCoreBundle:Default:geospatial.html.twig', array('locations' => $locations));
它返回错误:
An exception has been thrown during the rendering of a template ("localhost:27017: can't find any special indices: 2d (needs index), 2dsphere (needs index), for: { coordinates: { $near: [ -8.688038000000001, 115.171329 ] } }") in MyCoreBundle:Default:geospatial.html.twig at line 1.
我错过了什么?
答案 0 :(得分:2)
您只能对正确编制索引的字段使用geospacial查询。 尝试创建一个字段(比如位置),这个数组只包含经度和纬度(不是键/值,只是两个普通值),并为其添加2d或2dsphere索引。
答案 1 :(得分:1)
您是否更新了索引?
当您创建索引(通过注释或通过外部映射文件)时,请记住运行实际创建索引的命令和数据库上的空集合:
app/console doctrine:mongodb:schema:update
请务必在生产数据库中运行它。
确保您的索引在那里:
在Mongo shell中运行:
db.WorkoutLocation.stats();