在弹性搜索中设置动态日期格式

时间:2015-04-28 16:11:09

标签: java sorting datetime elasticsearch

我是Elastic Search的新手。

我有一个用户映射,并且与用户关联的是嵌套对象extraDataValues。在这个对象中是id,一个字符串值和另一个嵌套对象。例如:

"extraDataValues": [
    {
        "id": 1,
        "value": "01/01/2016 00:00:00",
        "id": 10,
            "label": "Metadata Date",
            "displayable": true
        },
    },
    {
        "id": 2,
        "value": "aaaa",
        "id": 11,
            "label": "Metadata TextBox",
            "displayable": true
        },
    }
],

如您所见,值字段可以是日期或普通字符串。问题出现在这里,我希望能够对这个值进行排序,因为它可以是日期或普通字符串。此外,日期可以采用两种格式:"dd/MM/yyyy HH:mm:ss", "dd/MM/yyyy"。我怎样才能首先使用Elastic Search(所以我能理解理论)然后使用Java?

我尝试添加"dynamic_date_formats" : ["dd/MM/yyyy HH:mm:ss", "dd/MM/yyyy"] 无济于事。

用户的映射是:

    User Mapping Document
{
    "User": {
       "properties": {
            "fullName": {
                "type": "string",
                "index":    "not_analyzed",
                "fields": {
                    "raw_lower_case": { 
                        "type":  "string",
                        "analyzer": "case_insensitive"
                    }
                }
            },              
            "username": {
                "type": "string",
                "index":    "not_analyzed",
                "fields": {
                    "raw_lower_case": { 
                        "type":  "string",
                        "analyzer": "case_insensitive"
                    }
                }
            },
            "email": {
                "type": "string",
                "index":    "not_analyzed",
                "fields": {
                    "raw_lower_case": { 
                        "type":  "string",
                        "analyzer": "case_insensitive"
                    }
                }
            },
            "firstName": {
                "type": "string",
                "index":    "not_analyzed",
                "fields": {
                    "raw_lower_case": { 
                        "type":  "string",
                        "analyzer": "case_insensitive"
                    }
                }
            },
            "surname": {
                "type": "string",
                "index":    "not_analyzed",
                "fields": {
                    "raw_lower_case": { 
                        "type":  "string",
                        "analyzer": "case_insensitive"
                    }
                }
            },
            "id": {
                "type": "long"
            },
            "extraDataValues": {
                "type": "nested",
                "dynamic_date_formats" : ["dd/MM/yyyy HH:mm:ss", "dd/MM/yyyy"],
                "properties": {
                    "extraDataValueObject": {
                        "properties": {
                            "id": {
                                "type": "long"
                            },
                            "label": {
                                "type": "string"
                            },
                            "displayable": {
                                "type": "boolean"
                            }
                        }
                    },
                    "value": {
                        "type": "string",
                        "index":    "not_analyzed",
                        "fields": {
                            "raw_lower_case": { 
                                "type":  "string",
                                "analyzer": "case_insensitive"
                            }
                        }
                    }
                }
            }   
        }
    }
}

1 个答案:

答案 0 :(得分:2)

你不能按照你想要的方式去做。 dynamic_date_formats仅用于动态添加的日期字段,不适用于您在映射中指定的日期字段(来自the documentation)。

我建议尝试的是这种映射:

   "value": {
      "type": "string",
      "fields": {
        "date1": {
          "type": "date",
          "format": "dd/MM/yyyy HH:mm:ss",
          "ignore_malformed": "true"
        },
        "date2": {
          "type": "date",
          "format": "dd/MM/yyyy",
          "ignore_malformed": "true"
        }
      }
    }

如果您有一个string字段(对于值的字符串类型部分),则为其定义两个子字段,每个子字段具有不同的日期格式。如果你真的有一个"ignore_malformed": "true"而不是一个约会的日期,那么必须让他们string

通过这种方式,您可以将其编入索引:

POST /my_index/user/1
{
  "value": "aaa"
}
POST /my_index/user/2
{
  "value": "01/01/2016 00:00:00"
}
POST /my_index/user/3
{
  "value": "02/02/2016"
}

您可以在查询中区分哪种类型的日期或字符串被编入索引:

  "query": {
    "filtered": {
      "filter": {
        "exists": {
          "field": "value.date2"
        }
      }
    }
  }

如果ES能够将value.date2下的内容编入索引,那么您将获得该文档。当然,value.date1也是如此。