找不到任何特殊指数:2d(需要指数),2dsphere(需要指数)

时间:2013-04-26 07:35:20

标签: doctrine-odm symfony-2.2

我正在尝试使用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. 

我错过了什么?

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

您是否更新了索引?

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

app/console doctrine:mongodb:schema:update

请务必在生产数据库中运行它。


确保您的索引在那里:

在Mongo shell中运行:

db.WorkoutLocation.stats();