Elasticsearch按自定义created_at字段排序 [英] Elasticsearch sort by custom created_at field

查看:93
本文介绍了Elasticsearch按自定义created_at字段排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've got a created_at field in my Elastic Search database and I'm trying to pull out data and sort it by that field. The field was stored with a mapping property with the date format, with the fielddata key set to true, but I still get the error:

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

Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [created_at] in order to load field data by uninverting the inverted index. Note that this can use significant memory.

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

One suggestion is that I can add the word keyword to my field to search it, but this seems to tell me that:

created_at未定义

created_at is not defined

我正在使用Javascript,而且我知道您不能仅添加(点)字符,因此我将其包装起来,但仍然无法正常工作. elastic.find 只是我编写的用于提取数据的函数,如果我删除 sort 数组,它将起作用.

I'm using Javascript, and I know you can't just add the (dot) character, so I've wrapped it and it still isn't working. elastic.find is just a function I've written to pull data, if I remove the sort array, it works.

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 ?

推荐答案

您的日期不应该是字符串/单词,而是

Your dates shouldn't be strings/kewords but rather mapped as dates. Let me walk you through it.

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 are some more official examples.

顺便说一句,以上代码段旨在相互独立工作,但在实际应用中,您不希望使用单独的异步闭包,而是一个具有多个等待状态的异步进程.我的意思是,执行顺序很重要.

这篇关于Elasticsearch按自定义created_at字段排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆