【问题标题】:Is it possible to apply a function to a field when making the search?进行搜索时是否可以将功能应用于字段?
【发布时间】:2020-11-27 10:54:43
【问题描述】:

我想在现在映射到 textdate 字段上进行 Range 搜索。问题是那个领域已经有数据了。所以删除索引并重新创建一个新的index 以将字段映射为date 不是一个好主意。所以我想在该字段上应用一个自定义函数来进行Range 搜索。这可能吗?

【问题讨论】:

    标签: elasticsearch elastica


    【解决方案1】:

    选项 1:无需删除和重新创建整个索引即可更新文档。

    如果为索引启用了存储,您可以创建具有正确数据类型的子字段。例如如果现有字段名称为dateText,那么您可以按如下方式更新索引映射,并利用查询更新来重新索引所有文档。

    PUT myindex/_mapping
    {
      "properties": {
        "datetext": {
          "type": "text",
          "fields": {
            "dateField": {
              "type": "date",
              "format": "yyyy-MM-dd HH:mm:ss"   //<--- change this as per the data
            }
          }
        }
      }
    }
    

    更新映射后使用update by query

    POST myindex/_update_by_query?conflicts=proceed
    

    完成上述操作后,您可以在dateText.dateField 上使用范围查询。

    选项 2:您可以使用 script query 处理文本到日期的转换并应用范围逻辑。

    【讨论】:

      【解决方案2】:

      当然可以使用脚本查询,但您的文本字段要么需要设置fielddata: true,要么是.keyword 类型(例如multifield),脚本才能访问字段值。

      处理完之后,假设您的文本字段 dateFieldAsText 包含以秒为单位的纪元时间戳,并且您希望使用人类可读的日期范围过滤 gte & lte。然后我们可以将所有内容解析为毫秒,然后进行简单的比较:

      {
        "query": {
          "script": {
            "script": {
              "source": """
                def doc_ts_milli = Integer.parseInt(doc['dateFieldAsText'].value) * 1000L;
                
                def df = new SimpleDateFormat("yyyy/MM/dd");
                def gte_ts = df.parse(params.gte).getTime();
                def lte_ts = df.parse(params.lte).getTime();
                
                return doc_ts_milli >= gte_ts && doc_ts_milli <= lte_ts
              """,
              "params": {
                "gte": "2020/01/01",
                "lte": "2021/01/01"
              }
            }
          }
        }
      }
      

      这样做的挑战是脚本在每个查询中都会重新初始化(除非they're stored),因此速度很慢。因此,最好的方法是使用新的日期字段更新映射,然后将_reindex 调用到update all docs。无需删除索引。

      现在这种方法的问题是它不会影响任何新的传入文档。在这种情况下,您可以修改您的摄取流程以也包含该新日期字段(因此您将有两个字段,由于遗留原因具有相同的值),或者您建立一个摄取管道来为您执行此操作(-> 没有摄取流程调整需要)。这是such a pipeline 的一个示例,尽管其目的略有不同。原理是一样的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多