2016-01-21 82 views
3

“星期几”我有一个类中的下列财产:Elasticsearch - 日期时间映射

public DateTime InsertedTimeStamp { get; set; } 

通过以下映射在ES

"insertedTimeStamp ":{ 
    "type":"date", 
    "format":"yyyy-MM-ddTHH:mm:ssZ" 
}, 

我想运行聚合返回按照“星期几”分组的所有数据,即“星期一”,“星期二”...等

我知道我可以在聚合调用中使用'脚本'来执行此操作,see here,然而,从米如果有大量文件(这里反对,认为分析日志),使用脚本对性能的影响不会有微不足道的影响。

有没有一种方法可以将属性与'子属性'进行映射。即用字符串我可以这样做:

"somestring":{ 
    "type":"string", 
    "analyzer":"full_word", 
    "fields":{ 
     "partial":{ 
      "search_analyzer":"full_word", 
      "analyzer":"partial_word", 
      "type":"string" 
     }, 
     "partial_back":{ 
      "search_analyzer":"full_word", 
      "analyzer":"partial_word_back", 
      "type":"string" 
     }, 
     "partial_middle":{ 
      "search_analyzer":"full_word", 
      "analyzer":"partial_word_name", 
      "type":"string" 
     } 
    } 
}, 

所有以.net代码在类中的一个属性。

我可以做一些类似的事情,分别存储'完整日期'和'年份','月份'和'日'等(索引时某种'脚本'),或者我需要做更多类中的属性并分别映射它们?这是Transform做的吗? (这是现在贬值,因此似乎表明我需要单独的领域......)

回答

4

绝对有可能在索引时使用pattern_capture token filter来做到这一点。

您首先要为每个日期部分定义一个分析器+标记过滤器组合,并将其分配给日期字段的子字段。每个令牌过滤器将只捕获组是感兴趣的

{ 
    "settings": { 
    "analysis": { 
     "analyzer": { 
     "year_analyzer": { 
      "type": "custom", 
      "tokenizer": "keyword", 
      "filter": [ 
      "year" 
      ] 
     }, 
     "month_analyzer": { 
      "type": "custom", 
      "tokenizer": "keyword", 
      "filter": [ 
      "month" 
      ] 
     }, 
     "day_analyzer": { 
      "type": "custom", 
      "tokenizer": "keyword", 
      "filter": [ 
      "day" 
      ] 
     }, 
     "hour_analyzer": { 
      "type": "custom", 
      "tokenizer": "keyword", 
      "filter": [ 
      "hour" 
      ] 
     }, 
     "minute_analyzer": { 
      "type": "custom", 
      "tokenizer": "keyword", 
      "filter": [ 
      "minute" 
      ] 
     }, 
     "second_analyzer": { 
      "type": "custom", 
      "tokenizer": "keyword", 
      "filter": [ 
      "second" 
      ] 
     } 
     }, 
     "filter": { 
     "year": { 
      "type": "pattern_capture", 
      "preserve_original": false, 
      "patterns": [ 
      "(\\d{4})-\\d{2}-\\d{2}[tT]\\d{2}:\\d{2}:\\d{2}[zZ]" 
      ] 
     }, 
     "month": { 
      "type": "pattern_capture", 
      "preserve_original": false, 
      "patterns": [ 
      "\\d{4}-(\\d{2})-\\d{2}[tT]\\d{2}:\\d{2}:\\d{2}[zZ]" 
      ] 
     }, 
     "day": { 
      "type": "pattern_capture", 
      "preserve_original": false, 
      "patterns": [ 
      "\\d{4}-\\d{2}-(\\d{2})[tT]\\d{2}:\\d{2}:\\d{2}[zZ]" 
      ] 
     }, 
     "hour": { 
      "type": "pattern_capture", 
      "preserve_original": false, 
      "patterns": [ 
      "\\d{4}-\\d{2}-\\d{2}[tT](\\d{2}):\\d{2}:\\d{2}[zZ]" 
      ] 
     }, 
     "minute": { 
      "type": "pattern_capture", 
      "preserve_original": false, 
      "patterns": [ 
      "\\d{4}-\\d{2}-\\d{2}[tT]\\d{2}:(\\d{2}):\\d{2}[zZ]" 
      ] 
     }, 
     "second": { 
      "type": "pattern_capture", 
      "preserve_original": false, 
      "patterns": [ 
      "\\d{4}-\\d{2}-\\d{2}[tT]\\d{2}:\\d{2}:(\\d{2})[zZ]" 
      ] 
     } 
     } 
    } 
    }, 
    "mappings": { 
    "test": { 
     "properties": { 
     "date": { 
      "type": "date", 
      "format": "yyyy-MM-dd'T'HH:mm:ssZ", 
      "fields": { 
      "year": { 
       "type": "string", 
       "analyzer": "year_analyzer" 
      }, 
      "month": { 
       "type": "string", 
       "analyzer": "month_analyzer" 
      }, 
      "day": { 
       "type": "string", 
       "analyzer": "day_analyzer" 
      }, 
      "hour": { 
       "type": "string", 
       "analyzer": "hour_analyzer" 
      }, 
      "minute": { 
       "type": "string", 
       "analyzer": "minute_analyzer" 
      }, 
      "second": { 
       "type": "string", 
       "analyzer": "second_analyzer" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

然后,当你指数的日期,如2016-01-22T10:01:23Z,你会得到每一个填入相关的部分,即日期子场

  • date2016-01-22T10:01:23Z
  • date.year2016
  • date.month01
  • date.day22
  • date.hour10
  • date.minute01
  • date.second23

你就可以自由地聚集在任何这些子领域的得到你想要的东西。

+0

主要使用此解决方案结束。我确实添加了第二个字段来实际存储'日',因为我想保持日期格式符合ISO,但是这绝对简化了解决方案。 –

+0

谢谢。我很高兴这对你有帮助! – Val

+0

这很好,但是如果我想'year','month'等等是关键字呢? –

2

我认为你唯一的选择似乎是scripted upsert这将允许您在索引时运行scripts

我创造了基本指标这样

POST user_index 
{ 
    "mappings": { 
    "users": { 
     "properties": { 
     "timestamp": { 
      "type": "date", 
      "format" : "yyyy-MM-dd'T'HH:mm:ssZ" 
     }, 
     "month":{ 
      "type" : "string" 
     }, 
     "day_of_week" : { 
      "type" : "string" 
     }, 
     "name" : { 
      "type" : "string" 
     } 
     } 
    } 
    } 
} 

那么你应该索引你的文件这样

POST user_index/users/111/_update/ 
{ 
    "scripted_upsert": true, 
    "script": "ctx._source.month = DateTime.parse('2014-03-01T10:30:00').toString('MMMM');ctx._source.day_of_week = DateTime.parse('2014-03-01T10:30:00').dayOfWeek().getAsText()", 
    "upsert": { 
    "name": "Brad Smith", 
    "timestamp": "2014-03-01T10:30:00Z" 
    } 
} 

这将索引文件是这样,更多datetime操作

{ 
    "_index": "user_index", 
    "_type": "users", 
    "_id": "111", 
    "_score": 1, 
    "_source": { 
     "timestamp": "2014-03-01T10:30:00Z", 
     "day_of_week": "Saturday", 
     "name": "Brad Smith", 
     "month": "March" 
    } 
} 

现在您可以轻松执行aggregations。另外请注意,您必须为此启用dynamic scripting,最好将脚本放在config/scripts文件夹中,并将timestamp作为params。您也可能只想根据您的要求将所有内容放入脚本中。

希望这有助于!

+0

我最终在这个实例中使用了来自@Val的解决方案,但+1提醒我关于upsert。 –

+0

很高兴能帮到你! – ChintanShah25

相关问题