ElasticsearchDSL icon indicating copy to clipboard operation
ElasticsearchDSL copied to clipboard

How do you do this sort

Open zhmm opened this issue 5 years ago • 2 comments

like query: GET xxx/_search { "sort": { "_script": { "script": "Math.random()", "type": "number", "order": "asc" } }, "query": { } } I didn't find the relevant documents, and I don't know how to implement such a random sort, thank you

zhmm avatar May 22 '20 03:05 zhmm

Any news on this? Would need something like this too.

  "sort": [
    {
      "_script": {
        "script": {
          "lang": "painless",
          "inline": "doc[\"in_city_map\"].value.contains(\"12e1f7c4-42d3-11ec-aa10-0242ac110003\") ? 1 : 0"
        },
        "type": "number",
        "order": "asc"
      }
    }
  ],

maluramichael avatar Nov 18 '21 15:11 maluramichael

Alright fixed it myself

$search->addSort(
    new ScriptSort(
        sprintf('doc["in_city_map"].value.contains("%s") ? 1 : 0', $city->getId()),
        FieldSort::DESC
    )
);
class ScriptSort implements BuilderInterface
{
    use ParametersTrait;

    const ASC  = 'asc';
    const DESC = 'desc';

    /**
     * @var string
     */
    private $source;

    /**
     * @var string
     */
    private $order;

    /**
     * @var string
     */
    private $type;

    /**
     * @var BuilderInterface
     */
    private $nestedFilter;

    /**
     * @param string $source Source code.
     * @param string|null $order Order direction.
     * @param array $params Params that can be set to field sort.
     */
    public function __construct(string $source, ?string $order = FieldSort::ASC, ?string $type = 'number', array $params = [])
    {
        $this->source = $source;
        $this->order  = $order;
        $this->type   = $type;
        $this->setParameters($params);
    }

    /**
     * @return string
     */
    public function getSource(): string
    {
        return $this->source;
    }

    /**
     * @param string|null $source
     *
     * @return $this
     */
    public function setSource(?string $source): ScriptSort
    {
        $this->source = $source;

        return $this;
    }

    /**
     * @return string
     */
    public function getOrder(): ?string
    {
        return $this->order;
    }

    /**
     * @param string|null $order
     *
     * @return $this
     */
    public function setOrder(?string $order): ScriptSort
    {
        $this->order = $order;

        return $this;
    }

    /**
     * Returns element type.
     *
     * @return string
     */
    public function getType()
    {
        return 'sort';
    }

    /**
     * {@inheritdoc}
     */
    public function toArray()
    {
        if ($this->order) {
            $this->addParameter('order', $this->order);
        }

        if ($this->nestedFilter) {
            $this->addParameter('nested', $this->nestedFilter->toArray());
        }

        $output = [
            '_script' => [
                'script' => [
                    'inline' => $this->source,
                    'lang'   => 'painless',
                ],
                'type'   => $this->type,
                'order'  => $this->order,
            ],
        ];

        return $output;
    }
}

maluramichael avatar Nov 18 '21 17:11 maluramichael