2013-04-26 111 views
0

我正在嘗試使用MongoDB的GeoSpatial功能。我有這樣的文件:找不到任何特殊索引:2d(需要索引),2dsphere(需要索引)

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

我缺少什麼?

回答

1

您已更新指標?

當您創建一個索引(通過註釋,或通過外部映射文件),記得運行實際上將創建索引,並在你的數據庫空集合命令:

app/console doctrine:mongodb:schema:update 

一定要在生產數據庫上運行它。


要確認你的索引有:

在蒙戈外殼運行:

db.WorkoutLocation.stats(); 
+1

就我而言,這是問題所在。索引不會被創建。在錯誤消息中明確解釋,但我認爲只需添加Index \ keys註釋就可以工作。所以我在mongo shell上運行ensureIndex()命令。我沒有意識到'doctrine:schema:update'命令,它變得更容易。但是在運行'doctrine:schema:update'命令之前確保集合已經存在。 – Permana 2013-05-01 03:35:25

2

只能對正確索引的字段使用地理空間查詢。 嘗試創建一個字段(比如位置),它是一個只包含經度和緯度(不是鍵/值,只是兩個普通值)的數組,並且向其添加2d或2dsphere索引。

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

+0

我創建了一個場兩個子緯度和經度,但它不是數組,怎麼你把它轉換成數組? – Sekai 2014-01-13 11:26:53