Symfony2和Doctrine查询与距离(Lonigtude和Latitude)和大关系 - 奇怪的结果计数?

时间:2016-04-28 15:49:07

标签: mysql doctrine-orm query-builder symfony

我在很多实体之间有很大的关系模型。

菜单<> MenuSection<>部分<> SectionEntry<>条目

条目<> EntryTag<>标签

菜单<> MenuLocation<>位置

“位置”实体获得经度和纬度等属性,以计算用户当前位置与“位置”之间的距离。

我写了一个更大的学说查询。 是的,存在许多关系(多对多,多对一等等,但关系表(例如entry_section)存在以在其上存储更多数据)。 让我告诉你我的问题。

$d = $this->getDoctrine()->getRepository('AppBundle:Entry')->createQueryBuilder('entry')
    ->select('entry')
    ->innerJoin('AppBundle:SectionEntry', 'section_entry', 'WITH', 'section_entry.entry_id = entry.id')
    ->innerJoin('AppBundle:Section', 'section', 'WITH', 'section.id = section_entry.section_id')
    ->innerJoin('AppBundle:MenuSection', 'menu_section', 'WITH', 'menu_section.section_id = section.id')
    ->innerJoin('AppBundle:Menu', 'menu', 'WITH', 'menu.id = menu_section.menu_id')
    ->innerJoin('AppBundle:MenuLocation', 'menu_location', 'WITH', 'menu_location.menu_id = menu.id')
    ->innerJoin('AppBundle:Location', 'location', 'WITH', 'location.id = menu_location.location_id');

if (!empty($tags)) {

    $d->innerJoin('AppBundle:EntryTag', 'entry_tag', 'WITH', 'entry.id = entry_tag.entry_id')
        ->where('entry_tag.tag_id IN (' . implode(',', $tags) . ')');

}

$d->addSelect(
    '( 6371 * acos(cos(radians(' . $lat . '))' .
        '* cos( radians( location.latitude ) )' .
        '* cos( radians( location.longitude )' .
        '- radians(' . $long . ') )' .
        '+ sin( radians(' . $lat . ') )' .
        '* sin( radians( location.latitude ) ) ) ) as distance'
);

if ($dist != 0) {
    $d->andHaving('distance < :distance')
        ->setParameter('distance', $dist);
}

$d->addOrderBy('distance', 'ASC')
    ->addOrderBy('location.id', 'ASC')
    ->setFirstResult(0)
    ->setMaxResults(20);

$entries = $d->getQuery()->getResult();

foreach ($entries as $no => $entry) {

    echo '[' . ($no+1) . ']' . $entry[0]->getId() . ': ' . $entry[0]->getSectionEntry()->first()->getSection()->getMenuSection()->first()->getMenu()->getMenuLocations()->first()->getLocation()->getAddress() . ' (' . $entry['distance'] . ')<br />'; // debug

}
// $entry[0]->getSectionEntry()->first()->getSection()->getMenuSection()->first()->getMenu()->getMenuLocations()->first()->getLocation()->getAddress() is very long :-) debug reason

die();

结果有问题。没有错误,但结果是有点混乱。 我尝试让Entries,内部联接表到达与之相关的“location”类,一次计算距离。我想用 - &gt; setMaxResults(20)限制结果(条目),例如20.一切都很好。但: 它的条目数少于20个。数据库中有100个,200个左右。 但它会给我11或12或其他东西。

我不知道这里发生了什么。我认为doctrine在后台进行多个SQL查询。他需要~3个查询来获得结果的一个条目。所以如果我写:setMaxResults(3)我会得到1个条目。 6将获得2个条目,依此类推。这只是一种怀疑。我不知道。这就是为什么我要求你的帮助:)。

我尝试添加 - &gt; addGroupBy('entry.id')...然后我得到正确数量的结果! setMaxResult(10)提供10个结果然后距离很奇怪。

让我举个例子。 当我使用 - &gt; addGroupBy('entry.id')和 - &gt; setMaxResult(30)时,doctrine会提供30个条目及其距离! 但是一些结果项目不正确(距离错误)。让我演示给你看。 例如,结果:

0, Entry, location_id 1, distance=1,8
1, Entry, location_id 1, distance=1,8
2, Entry, location_id 1, distance=1,8
3, Entry, location_id 1, distance=1,8
4, Entry, location_id 1, distance=1,8
5, Entry, location_id 1, distance=1,8
6, Entry, location_id 1, distance=1,8
7, Entry, location_id 1, distance=1,8
8, Entry, location_id 1, distance=1,8
9, Entry, location_id 1, distance=1,8
10, Entry, location_id 1, distance=1,8
11, Entry, location_id 1, distance=1,8
12, Entry, location_id 1, distance=1,8
13, Entry, location_id 1, distance=1,8
14, Entry, location_id 1, distance=1,8
15, Entry, location_id 2, distance=1,8
16, Entry, location_id 2, distance=1,8
17, Entry, location_id 2, distance=1,8
18, Entry, location_id 2, distance=1,8
19, Entry, location_id 2, distance=1,8
20, Entry, location_id 2, distance=4,5
21, Entry, location_id 2, distance=4,5
22, Entry, location_id 2, distance=4,5
23, Entry, location_id 2, distance=4,5
24, Entry, location_id 2, distance=4,5
25, Entry, location_id 2, distance=4,5
26, Entry, location_id 2, distance=4,5
27, Entry, location_id 2, distance=4,5
28, Entry, location_id 2, distance=4,5
29, Entry, location_id 2, distance=4,5
30, Entry, location_id 2, distance=4,5

1,8和4,5是正确的!但你可以看到,这些结果项的距离是错误的:

15, Entry, location_id 2, distance=1,8
16, Entry, location_id 2, distance=1,8
17, Entry, location_id 2, distance=1,8
18, Entry, location_id 2, distance=1,8
19, Entry, location_id 2, distance=1,8

location_id是另一个位置,但是15,16,17,18和19与location_id 1的距离相同。

所以这很奇怪。但为什么? 我认为我在以正确的方式编写教义查询时遇到了一些问题。

你可以帮我解决这个问题吗?

0 个答案:

没有答案