0

我正在尝试使用 MongoDB 的地理空间功能。我有这个文件:

<?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. 

我错过了什么?

4

2 回答 2

2

您只能对正确索引的字段使用地理空间查询。尝试创建一个字段(例如,位置),它是仅包含经度和纬度的数组(不是键/值,只是两个普通值),并为其添加 2d 或 2dsphere 索引。

http://docs.mongodb.org/manual/core/geospatial-indexes/

于 2013-04-26T12:07:36.730 回答
1

你更新你的索引了吗?

当您创建索引(通过注释或通过外部映射文件)时,请记住运行将在您的数据库上实际创建索引和空集合的命令:

app/console doctrine:mongodb:schema:update

请务必在您的生产数据库上运行它。


为确保您的索引在那里:

在 Mongo shell 中运行:

db.WorkoutLocation.stats();
于 2013-04-29T09:28:15.427 回答