基于MongoDB-ODM的地理空间查询
我在文档的坐标属性上有一个二维索引。使用mongo shell,我可以像这样查询集合基于MongoDB-ODM的地理空间查询,mongodb,doctrine-odm,Mongodb,Doctrine Odm,我在文档的坐标属性上有一个二维索引。使用mongo shell,我可以像这样查询集合 db.adverts.find({coordinates:{$near:[20,40]}}) Advert: type: document collection: adverts fields: id: id: true title: type: string content:
db.adverts.find({coordinates:{$near:[20,40]}})
Advert:
type: document
collection: adverts
fields:
id:
id: true
title:
type: string
content:
type: string
created:
type: date
updated:
type: date
status:
type: int
distance:
type: int
indexes:
coordinates:
keys:
coordinates: 2d
referenceOne:
owner:
targetDocument: User
embedOne:
coordinates:
targetDocument: Coordinates
Coordinates:
type: embeddedDocument
fields:
longitude:
type: float
latitude:
type: float
并返回以下结果,如预期的那样
{ "_id" : ObjectId("4fddac51352de93903000000"), "title" : "dummy #3", "coordinates" : { "longitude" : 22, "latitude" : 31 } }
{ "_id" : ObjectId("4fddac48352de95105000000"), "title" : "dummy #3", "coordinates" : { "longitude" : 20, "latitude" : 30 } }
{ "_id" : ObjectId("4fddaca4352de93703000000"), "title" : "dummy #3", "coordinates" : { "longitude" : 31, "latitude" : 22 } }
{ "_id" : ObjectId("4fdda6a2352de90a03000000"), "title" : "dummy title", "created" : ISODate("2012-06-17T09:42:58Z"), "coordinates" : { "longitude" : 54.1234, "latitude" : -1.234 } }
{ "_id" : ObjectId("4fdda6d8352de9c004000000"), "title" : "dummy title #2", "created" : ISODate("2012-06-17T09:43:52Z"), "coordinates" : { "longitude" : 54.34, "latitude" : -1.124 } }
然而,根据文档使用条令来查询完全相同的集合,我没有得到任何结果,例如
$adverts = $dm->createQueryBuilder('Advert')
->field('coordinates')->near(20, 40)
->getQuery()
->execute();
$adverts->count(); // => 0
我的广告yaml看起来像这样
db.adverts.find({coordinates:{$near:[20,40]}})
Advert:
type: document
collection: adverts
fields:
id:
id: true
title:
type: string
content:
type: string
created:
type: date
updated:
type: date
status:
type: int
distance:
type: int
indexes:
coordinates:
keys:
coordinates: 2d
referenceOne:
owner:
targetDocument: User
embedOne:
coordinates:
targetDocument: Coordinates
Coordinates:
type: embeddedDocument
fields:
longitude:
type: float
latitude:
type: float
坐标文件是这样的
db.adverts.find({coordinates:{$near:[20,40]}})
Advert:
type: document
collection: adverts
fields:
id:
id: true
title:
type: string
content:
type: string
created:
type: date
updated:
type: date
status:
type: int
distance:
type: int
indexes:
coordinates:
keys:
coordinates: 2d
referenceOne:
owner:
targetDocument: User
embedOne:
coordinates:
targetDocument: Coordinates
Coordinates:
type: embeddedDocument
fields:
longitude:
type: float
latitude:
type: float
你知道为什么使用Doctrine的ODM会在同一个查询中返回零结果吗
更新#1
看起来条令\MongoDB\Query\Builder::near()L363有问题。方法参数忽略第二个值($y)。因此只传递第一个值以执行。near()方法似乎存在实现问题(请参阅)。要修复原始查询,我需要执行以下操作:
$adverts = $dm->createQueryBuilder('Advert')
->field('coordinates.latitude')->near(20)
->field('coordinates.longitude')->near(40);
$adverts->getQuery()->count(); // => 5
这与当前说明x、y坐标都可以传递给Doctrine\MongoDB\Query\Builder::near()的文档相矛盾
编辑
为了简化工作,我创建了一个自定义存储库类,为这种不一致性提供了更直观的解决方案
public function near($longitude, $latitude)
{
$query = $this->createQueryBuilder()
->field('coordinates.longitude')->near((float) $longitude)
->field('coordinates.latitude')->near((float) $latitude)
->getQuery();
return $query;
}
这可能是一个愚蠢的问题,但不应该在Advert.yaml中将坐标定义为一个字段,因为它毕竟是一个字段。或者这就是EmbedOne的目的。getQuery()返回什么?另外,请注意MongoDB希望坐标字段中的顺序为:纬度、经度。它不关心字段的调用。Derick-getQuery()返回一个doctor\ODM\MongoDB\Query\Query的实例。Geoist-embedOne指定坐标属性