Elasticsearch 按自定义 created_at 字段排序

问题描述

我的 Elastic Search 数据库中有一个 created_at 字段,我正在尝试提取数据并按该字段对其进行排序。该字段与日期格式的映射属性一起存储,fielddata 键设置为 true,但我仍然收到错误

文本字段未针对需要按文档字段数据(如聚合和排序)的操作进行优化,因此认情况下禁用这些操作。请改用关键字字段。或者,在 [created_at] 上设置 fielddata=true 以通过反转倒排索引加载字段数据。请注意,这会占用大量内存。

一个建议是我可以在我的字段中添加单词 keyword 以进行搜索,但这似乎告诉我:

created_at 未定义

我正在使用 Javascript,我知道您不能只添加(点)字符,所以我已经将它包装起来,但它仍然无法正常工作。 elastic.find 只是我为提取数据而编写的函数,如果我删除 sort 数组,它就可以工作。

const results = await elastic.find('my table',{
  query: {
    range: {
      created_at: {
        gte: moment(from).format('YYYY-MM-DD HH:MM:SS')
      }
    }
  },sort: [{
    [created_at.keyword]: 'asc' // seems to be undefined
  }]
})

为什么我无法访问 created_at.keyword

database

解决方法

您的日期不应该是字符串/关键字,而应该是 mapped as dates。让我带你完成它。

1.设置包和客户端

const { Client } = require("@elastic/elasticsearch");
const client = new Client({
  node: "http://localhost:9200"
});

const INDEX_NAME = "my_table";

2.创建索引

(async () => {
  const { body,statusCode } = await client.indices.create(
    {
      index: INDEX_NAME,body: {
        mappings: {
          properties: {
            created_at: {
              type: "date",format: "yyyy-MM-dd HH:mm:ss"
            }
          }
        }
      }
    },{ ignore: [400] }
  );

  if (body.error) {
    console.warn("createResponse err",body.error);
  } else {
    console.info("createResponse",{ body,statusCode });
  }
})();

3.添加一些文档

(async () => {
  const { body,statusCode } = await client.bulk({
    body: [
      // Doc #1
      { index: { _index: INDEX_NAME,_id: 1 } },{ created_at: "2021-02-19 00:00:00" },// Doc #2
      { index: { _index: INDEX_NAME,_id: 2 } },{ created_at: "2021-02-19 00:02:00" }
    ]
  });

  if (body.error) {
    console.warn("bulkResponse err",body.error);
  } else {
    console.info("bulkResponse",statusCode });
  }
})();

4.搜索和排序

(async () => {
  const { body,statusCode } = await client.search({
    index: INDEX_NAME,body: {
      size: 10,query: {
        range: {
          created_at: {
            gte: "2021-02-18 00:00:00"
          }
        }
      },sort: [
        {
          created_at: "asc"
        }
      ]
    }
  });

  if (body.error) {
    console.warn("searchResponse err",body.error);
  } else {
    // pretty print
    console.dir({ searchResponse: { body,statusCode } },{ depth: null });
  }
})();

Here 是一些更官方的例子。

顺便说一句,上述代码片段旨在彼此独立工作,但在实际应用程序中,您不想使用单独的异步闭包,而是使用一个具有多个等待的异步进程。我的意思是,执行顺序很重要。