【问题标题】:Elasticsearch Node.js date operators in query search查询搜索中的 Elasticsearch Node.js 日期运算符
【发布时间】:2021-02-19 17:43:32
【问题描述】:

我将数据存储在本地 Node JS Elastic Search 数据库中,现在我已插入记录,其中一个字段是 created_at 字段,我使用 new Date() 存储了该字段,但是,在检索数据,似乎这些是字符串,因此我的查询似乎没有返回任何结果。

我的数据如下:

{
    "_index": "my_table",
    "_type": "_doc",
    "_id": "V1mouXcBt3ZsPNCwd3A1",
    "_version": 1,
    "_seq_no": 0,
    "_primary_term": 1,
    "found": true,
    "_source": {
        "properties": {
            "created_at": {
                "type": "date",
                "format": "yyyy-MM-dd HH:mm:ss"
            },
            "updated_at": {
                "type": "date",
                "format": "yyyy-MM-dd HH:mm:ss"
            }
        },
        "data": {
            "name": "performance_overview",
            "friendly_name": "Performance Overview",
            "data": {
                "cached": "9:39:21am",
                "from": "02/19/2021 00:00:00",
                "to": "02/19/2021 23:59:59",
                "success": true,
                "message": "message",
                "sessions": "265",
                "leads": "123",
                "conversion_rate": "46.42"
            },
            "created_at": "2021-02-19 09:02:16",
            "updated_at": "2021-02-19 09:02:16"
        }
    }
}

我正在使用 Moment JS,并已格式化日期,并尝试了我认为对字段映射准确的方法,尽管我是 Elastic Search 的新手,这似乎也没有返回任何结果。

const from = moment(from).startOf('day')

const results = await elastic.find('my_table', {
  query: {
    range: {
      created_at: {
        gte: moment(from).format('YYYY-MM-DD HH:MM:SS'),
      }
    }
  }
})

elastic.find 是我编写的自定义函数,如下所示,是从另一个 JS 文件中导出的:

const find = async (table, data) => {
  try {
    const found = await client.search({
      index: table,
      body: data
    }, {
      ignore: [404],
      maxRetries: 3
    })

    return found.body
  } catch (err) {

    return err
  }
}

【问题讨论】:

    标签: javascript node.js elasticsearch


    【解决方案1】:

    Elasticsearch 是一个 JSON 输入、JSON 输出接口,可将您的日期时间数据存储为 strings of a given format(如果您选择的话,也可以是从纪元开始的数字(毫秒)秒。)

    至于为什么new Date() 被转换为字符串——在网络传输之前的某个时间点,JS 客户端将通过在其上调用JSON.stringifyserialize 包含文档的请求正文。当在 JS 对象上调用此函数时,JS 运行时会查找 .toJSON method on that object 的实现并序列化 this 方法返回的值。您可以通过运行来验证这一点:

    const date = new Date();
    console.assert(`"${date.toJSON()}"` === JSON.stringify(date))
    

    现在,在您的elastic.find('my_table', {...}) 通话中,您同时尝试了两件事——设置映射查询索引。那是行不通的。

    你必须define your mapping你摄取任何文件。执行此操作时,请确保您的日期字段具有 a proper format 以防止出现不一致:

    {
      "properties": {
        "created_at": {
          "type": "date",
          "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
        }
      }
    }
    

    然后将一些文档添加到您的表/索引中(通过index operation)。

    只有这样,您才能使用您的range 查询。 Here's a good working example.

    【讨论】:

    • 这是一个有用的答案,并且在某种程度上帮助我使用 properties 对象将数据放入我的表中,但是,在尝试检索数据时,仍然没有任何结果。您可以看到created_at 字段现在差不多了,我的查询是从一天的开始获取日期/时间,所以应该返回结果,但没有。我错过了什么?
    • 还是不行。映射properties 不应在数据本身中,而应在索引映射(表模式)中。您所做的是将表模式放在表行中。重新阅读我的答案,点击链接(尤其是“定义你的映射”部分),看看你是否启动并运行它。
    • 你知道@RyanHolton 了吗?
    猜你喜欢
    • 1970-01-01
    • 2017-04-21
    • 2017-04-02
    • 1970-01-01
    • 2019-09-07
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    相关资源
    最近更新 更多