Home > Net >  Elasticsearch: Sort by _script using php client
Elasticsearch: Sort by _script using php client

Time:10-01

Is there a way to sort by _script from php client? I haven't found a way to achieve that, but I did manage to do it from cURL.

If I do the query from cURL I can do the following and it works.

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"
    }
  }
}

But if I do it from PHP the sort parameter is added to the query string and not to the post body. And I couldn't make it work.

First I tried:

$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();

And the result was: No mapping found for [Array] in order to sort on.

Then I tried to send the sort param encoded:

$params['sort'] = json_encode(['_script' => ["script" => ["source" => "doc['language'].value == 'en' ? 1 : 0"], "type" => "number", "order" => "desc"]]);

and I end up with the param in the query string and it doesn't work.

POST http://localhost:9200/index/_search?sort={"_script":{"script":{"source":"doc['language'].value == 'en' ? 1 : 0"},"type":"number","order":"desc"}}

Is there any way to make it work?

CodePudding user response:

I believe the sort should be inside the body.

$params['body']['sort'] = [
    "_script" => [
        "script" => ["source" => "doc['language'].value == 'en' ? 1 : 0"], 
        "type" => "number",
        "order" => "desc"
    ]
]
  • Related