【问题标题】:Elasticsearch sort by custom created_at fieldElasticsearch 按自定义 created_at 字段排序
【发布时间】:2021-05-22 08:11:45
【问题描述】:

我的 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

【问题讨论】:

    标签: javascript node.js elasticsearch elasticsearch-query elasticsearch-mapping


    【解决方案1】:

    您的日期不应该是字符串/关键字,而是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", { body, 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 是一些更官方的例子。

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

    【讨论】:

    • @Ryan 有意义吗?
    猜你喜欢
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多