Не могу найти никаких специальных индексов: 2d (нужен индекс), 2dsphere (нужен индекс)

Я пытаюсь использовать GeoSpatial в 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. 

Что мне не хватает?

2 ответа

Решение

Вы обновили свои индексы?

Когда вы создаете индекс (через аннотации или через внешний файл отображения), не забудьте запустить команду, которая фактически создаст индекс и пустую коллекцию в вашей базе данных:

app/console doctrine:mongodb:schema:update

Обязательно запустите его также на своей производственной базе данных.


Чтобы убедиться, что ваши индексы есть:

запустить в оболочке Монго:

db.WorkoutLocation.stats();

Вы можете использовать геопространственные запросы только для полей, которые проиндексированы надлежащим образом. Попробуйте создать одно поле (скажем, location), которое является массивом, содержащим только долготу и широту (не как ключ / значение, а только два простых значения), и добавьте в него 2d или 2dsphere индекс.

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

Другие вопросы по тегам