如何在Elasticsearch PHP客户端中使用_script进行排序?
Elasticsearch PHP客户端使用_script排序的解决方案
要在Elasticsearch PHP客户端中实现脚本排序,核心是把sort配置放在请求体(body数组)内,而不是作为顶级参数。你之前的错误在于将sort放在了$params的根节点,导致客户端把它解析成URL查询参数,而非请求体的一部分。
正确代码示例
$params = [ 'index' => self::INDEX_NAME, 'from' => $offset, 'size' => $pageSize, 'body' => [ // 将sort嵌套在body中,与query同级 'sort' => [ '_script' => [ 'type' => 'number', 'script' => [ 'source' => "doc['language'].value == 'en' ? 1 : 0" ], 'order' => 'desc' ] ], 'query' => [ 'bool' => [ 'must' => [ 'multi_match' => [ 'query' => $query, 'type' => 'best_fields', 'fields' => ['title', 'description', 'subject'], 'operator' => 'and' ] ] ] ] ] ]; /** * @var ElasticResponse */ $response = $this->elasticClient->search($params); $arrayResponse = $response->asArray();
错误原因说明
- 顶级sort参数的问题:你最初把
$params['sort']作为顶级参数时,PHP客户端会将其转换为URL查询参数(类似?sort=Array),这完全不符合Elasticsearch对脚本排序的结构要求,因此报出No mapping found for [Array] in order to sort on.。 - JSON编码后仍放URL的问题:后来用
json_encode处理sort参数,虽然序列化了结构,但依然放在URL中——复杂的脚本排序逻辑必须通过请求体传递,URL参数无法正确解析这种嵌套结构。
原问题背景
请问能否在Elasticsearch PHP客户端中使用_script进行排序?我尚未找到实现方法,但已通过cURL成功实现。
通过cURL执行查询的有效示例:
curl -X GET "localhost:9200/name/_search?pretty" -H 'Content-Type: application/json' -d' { "query":{"bool":{"must":{"multi_match":{"query":"hello","type":"best_fields","fields":["title","description"],"operator":"and"}}}}, "sort": { "_script": { "type": "number", "script": { "source": "doc[\u0027language\u0027].value == \u0027en\u0027 ? 1 : 0" }, "order": "desc" } } } '
但使用PHP客户端时,sort参数会被添加到查询字符串而非请求体中,无法正常工作。
我首先尝试的代码:
$params = [ 'index' => self::INDEX_NAME, 'from' => $offset, 'size' => $pageSize, 'body' => [], ]; $params['sort'] = ['_script' => ["script" => ["source" => "doc['language'].value == 'en' ? 1 : 0"], "type" => "number", "order" => "desc"]]; $params['body']['query']['bool']['must']['multi_match'] = [ 'query' => $query, 'type' => 'best_fields', 'fields' => [ 'title', 'description', 'subject', ], 'operator' => 'and', ]; /** * @var ElasticResponse */ $response = $this->elasticClient->search($params); $arrayResponse = $response->asArray();
结果报错:No mapping found for [Array] in order to sort on.
之后我尝试对sort参数进行编码:
$params['sort'] = json_encode(['_script' => ["script" => ["source" => "doc['language'].value == 'en' ? 1 : 0"], "type" => "number", "order" => "desc"]]);
此时sort参数出现在查询字符串中,仍无法正常工作:
POST http://localhost:9200/index/_search?sort=%7B%22_script%22%3A%7B%22script%22%3A%7B%22source%22%3A%22doc%5B%27language%27%5D.value+%3D%3D+%27en%27+%3F+1+%3A+0%22%7D%2C%22type%22%3A%22number%22%2C%22order%22%3A%22desc%22%7D%7D
请问有可行的解决方法吗?
内容的提问来源于stack exchange,提问作者Khriz
相关产品推荐
相关产品推荐

