首页 > 解决方案 > ElasticSearch Rails:如果存在和将来按日期1排序,否则按日期2排序

问题描述

在此处输入图像描述

Posts以上是我们存储在 elasticsearch 中的模型的两条不同记录。我们正在尝试添加逻辑,使我们的粘性帖子在它们过期后像常规帖子一样放在提要中。

我们想让它说

“如果is_stickyANDstickied_until在未来排序stickied_until,否则排序created_at

我想我让它在 SQL 中工作(因为我们在那里存储了大部分数据,并且只在 ES 中存储了可搜索的字段),看起来像

ORDER BY
  CASE
  WHEN stickied_until >= '#{DateTime.now.utc}'
  THEN stickied_until
  ELSE created_at
END DESC

但是有两件事控制排序,我很确定这会导致错误,而且感觉不对。

是否可以在 ES 中进行这种条件排序?

标签: ruby-on-railselasticsearch

解决方案


您必须为此使用排序脚本。

{
  "sort": [
    {
      "_script": {
        "type": "number",
        "script": {
          "lang": "painless",
          "source": """
            def is_sticky = doc['is_sticky'].value;
            def created_at = doc['created_at'].value.getMillis();
            if (!is_sticky) {
              return created_at;
            }

            def stickied_until =  doc['stickied_until'].value.getMillis();
            def now = params['now'];

            if (is_sticky && stickied_until > now) {
              return stickied_until;
            }

            return created_at;
          """,
          "params": {
            "now": 1586798403888
          }
        },
        "order": "desc"
      }
    }
  ]
}

请注意,由于文档params['now']中解释的原因,我使用了查询时间常数。


推荐阅读