FOSElacticaBundle:无法解析 [geo_bbox] 查询。意外字段 [gte] [原因:所有分片失败]

FOSElacticaBundle: failed to parse [geo_bbox] query. unexpected field [gte] [reason: all shards failed]

我使用 FOSElasticaBundle 的 GeoBoundingBox [1] class 成功填充给定区域中的用户地图。现在我想添加一个条件,以便仅映射在过去 10 分钟内活跃的用户。所以我在 fos_elastica.yml 中添加了一个映射,比如

types:
    user:
        mappings:
            id: ~
            username: ~
            firstName: ~
            lastName: ~
            email: ~
            location:
                type: geo_point
            lastActivityAt:
                type: date
...

我 运行 fos:elastica:resetfos:elastica:populate,只是为了确保我有当前结果。这些命令 运行 成功。到目前为止一切顺利,我还清除了 Symfony 缓存。然后我在控制器中添加以下逻辑,我正在使用 AJAX 调用

$query = new GeoBoundingBox(
            'location',
            array(
                //top_left
                array(
                   'lat' => $data['north'],
                   'lon' => $data['west']
                ),
                //bottom_right
                array(
                    'lat' => $data['south'],
                    'lon' => $data['east']
                )
            )
        );

$earlier = new \DateTime('10 minutes ago');
$query->addParam('lastActivityAt', ['gte' => $earlier]);

$result = $this->get('fos_elastica.finder.app.user')->find($query);
...

这就是麻烦的开始。我在浏览器中刷新地图,在网络检查器中,我现在收到以下错误

failed to parse [geo_bbox] query. unexpected field [gte] [reason: all shards failed]

我显然在这里做错了什么。我对 Elasticsearch 了解不多。我怎样才能正确使用 Param::addParam() 来设置它?

[1] https://github.com/FriendsOfSymfony/FOSElasticaBundle

如错误消息所示,您不能将日期时间 range 查询添加到 geo_bounding_box 查询。您需要将两者都包装在所谓的布尔查询中。

您需要以下内容:

$boolQuery = new \Elastica\Query\BoolQuery();

$bboxQuery = new GeoBoundingBox(
            'location',
            array(
                //top_left
                array(
                   'lat' => $data['north'],
                   'lon' => $data['west']
                ),
                //bottom_right
                array(
                    'lat' => $data['south'],
                    'lon' => $data['east']
                )
            )
        );
$boolQuery->addMust($bboxQuery);

$rangeQuery = new Elastica\Query\Range();
        $earlier = new \DateTime('2 hours ago');
        $earlierString = substr($earlier->format(DateTimeInterface::ISO8601), 0, -5);
        $timeZone = substr($earlier->format(DateTimeInterface::ISO8601), -5, 5);
        $rangeQuery->addField(
            'lastActivityAt',
            [
                'time_zone'=> $timeZone,
                'gte' => $earlierString,
                'lte' => 'now'
            ]
        );
$boolQuery->addMust($rangeQuery);

$result = $this->get('fos_elastica.finder.app.user')->find($boolQuery);