Doctrine ODM geoNear距离未正确映射(始终为空)

时间:2015-08-20 13:48:50

标签: mongodb doctrine-orm geospatial doctrine-odm odm

我在执行geoNear查询时遇到了在文档中获取mongodb距离值的问题。

我有3个文件:Venue,嵌入位置,嵌入坐标。

这是" light"我模特的版本

地点:

/**
 * Venue
 * 
 * @ODM\Document(repositoryClass="CLabs\VenueBundle\Document\VenueRepository")
 */
class Venue
{
    /**
     * @var integer
     *
     * @ODM\Id(strategy="auto")
     */
    protected $id;

    /**
     * @var float
     *
     * @ODM\Distance
     * @ODM\NotSaved
     */
    public $distance;

    /**
     * @var \Location
     *
     * @ODM\EmbedOne(
     *      targetDocument="CLabs\LocationBundle\Document\Location"
     * )
     */
    protected $location;

    /**
     * Get id
     *
     * @return id $id
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set distance
     *
     * @param float $distance
     * @return self
     */
    public function setDistance($distance)
    {
        $this->distance = $distance;
        return $this;
    }

    /**
     * Get distance
     *
     * @return float $distance
     */
    public function getDistance()
    {
        return $this->distance;
    }

    /**
     * Set location
     *
     * @param CLabs\LocationBundle\Document\Location $location
     * @return self
     */
    public function setLocation(\CLabs\LocationBundle\Document\Location $location)
    {
        $this->location = $location;
        return $this;
    }

    /**
     * Get location
     *
     * @return CLabs\LocationBundle\Document\Location $location
     */
    public function getLocation()
    {
        return $this->location;
    }
}

地点:

/**
 * Location
 * 
 * @ODM\EmbeddedDocument
 * @ODM\Index(keys={"coordinates"="2d"})
 */
class Location
{
    /**
     * @var \Coordinates
     *
     * @ODM\EmbedOne(
     *      targetDocument="CLabs\LocationBundle\Document\Coordinates"
     * )
     */
    protected $coordinates;

    /**
     * Set coordinates
     *
     * @param CLabs\LocationBundle\Document\Coordinates $coordinates
     * @return self
     */
    public function setCoordinates(\CLabs\LocationBundle\Document\Coordinates $coordinates)
    {
        $this->coordinates = $coordinates;
        return $this;
    }

    /**
     * Get coordinates
     *
     * @return CLabs\LocationBundle\Document\Coordinates $coordinates
     */
    public function getCoordinates()
    {
        return $this->coordinates;
    }
}

坐标:

/**
 * Coordinates
 * @ODM\EmbeddedDocument
 */
class Coordinates
{
    /**
     * @var string
     *
     * @ODM\Float
     */
    protected $lng;

    /**
     * @var string
     *
     * @ODM\Float
     */
    protected $lat;

    /**
     * Set lng
     *
     * @param float $lng
     * @return self
     */
    public function setLng($lng)
    {
        $this->lng = $lng;
        return $this;
    }

    /**
     * Get lng
     *
     * @return float $lng
     */
    public function getLng()
    {
        return $this->lng;
    }

    /**
     * Set lat
     *
     * @param float $lat
     * @return self
     */
    public function setLat($lat)
    {
        $this->lat = $lat;
        return $this;
    }

    /**
     * Get lat
     *
     * @return float $lat
     */
    public function getLat()
    {
        return $this->lat;
    }
}

从这个模型中,当我在VenueRepository上进行geoNear查询时,就像这样:

$kmsMultiplier = 6378.137;

return $this->createQueryBuilder()
    ->geoNear((float)$lng, (float)$lat)
    ->maxDistance($maxDistance/$kmsMultiplier)
    ->spherical(true)
    // Convert radians to kilometers
    ->distanceMultiplier($kmsMultiplier)
    ->getQuery()
    ->execute();

我通过执行' $ result-> toArray()'来提取我的对象集合。 (或者只是关于结果的foreach),然后我想与我的对象保持距离,就像doctrine documentation中所解释的那样。

但是当我$venue->getDistance()时,它总是会返回null,即使mongodb正确计算了距离。

以下是此查询结果的示例:

    "elements": [
      {
        "id": "559f7b728b8ff7c1127b23c8",
        "location": {
          "coordinates": {
            "lng": 5.4190150243677,
            "lat": 43.533426029669
          }
        }
      }...
    ],
    "commandResult": {
      "results": [
        {
          "dis": 3.1465013027305,
          "obj": {
            "_id": {
              "$id": "559f7b728b8ff7c1127b23c8"
            },
            "location": {
              "coordinates": {
                "lng": 5.4190150243677,
                "lat": 43.533426029669
              }
            }
          }
        }...
      ],
      "stats": {
        "nscanned": 3,
        "objectsLoaded": 3,
        "avgDistance": 3.8863491981201,
        "maxDistance": 4.3498686266835,
        "time": 0
      },
      "ok": 1
    }

我尝试从Venue文档中删除我的get / setDistance,在位置文档中移动$ distance声明但没有任何效果,我距离$object->getDistance()$object->distance都不远。

我可以自己处理这个属性映射,但是使用Doctrine方法会更方便,好吧,如果它有效......我无法弄清楚我的错误在哪里,或者我的代码是责怪。

以下是我的composer.json示例:

"symfony/symfony": "v2.6.4",
"doctrine/mongodb": "v1.1.8",
"doctrine/mongodb-odm": "v1.0.0-BETA13",
"doctrine/mongodb-odm-bundle": "v3.0.0"

我在debian VM上安装了mongodb 2.6.11(Linux wheezy64 3.2.0-4-amd64#1 SMP Debian 3.2.68-1 + deb7u3 x86_64 GNU / Linux)。

您认为这是一个学说ODM问题吗?我是唯一一个遇到这个问题的人吗?

任何帮助表示赞赏

1 个答案:

答案 0 :(得分:0)

经过一番挖掘,我自己找到了解决方案。

首先我更新了一些捆绑包:

  • doctrine / mongodb => 1.2.0
  • doctrine / mongodb-odm => 1.0.1

但问题仍然存在。

事实上,我的模型似乎在注释@NotSaved@Distance之间存在冲突。我之前添加了@NotSaved注释,因为我在执行geoNear查询时曾经在以前的bundle版本中有映射错误。

这些问题必须在最新的捆绑版本中得到解决,因为从距离字段中删除@NotSaved注释后,我现在在geoNear查询中获取距离值,同时Doctrine也不再尝试在db中保存距离字段。