我使用Elasticsearch API和文档架构如下
{
name: "",
born_year: "",
born_month: "",
born_day: "",
book_type: "",
price: <some number>,
country: ""
}
现在我需要的是获得1995年之前出生的每个名字的文件数(born_year + born_month + born_day&lt;&#34; 20051220&#34;)。我怎样才能实现?
我试过了:
{
"query": {
"query_string": {
"query": "country:\"SL\""
}
},
"size": 0,
"aggs": {
"total": {
"terms": {
"field": "name"
}
}
}
}
但我不知道如何为生日添加过滤器。
答案 0 :(得分:1)
如@val所述,您需要添加一个真实的日期字段,您可以通过在创建时连接这三个字段来轻松添加。 但是如何根据日期范围进行过滤,有两种方法,它们都会返回不同的结果集 现在可以选择过滤级别。
您提到在国家/地区字段上查询。但是您没有提到要在日期范围内过滤的级别。我会给你两个案件的查询。
映射 - 假设您创建了一个日期字段。
{
name:"",
born_year:"",
born_month:"",
born_day:"",
book_type:"",
price:<some number>,
country:"",
date : ""
}
案例 - 1)仅过滤名称聚合的日期范围,此处文件计数不受日期范围过滤器的影响
{
"query": {
"query_string": {
"query": "country:\"SL\""
}
},
"aggs": {
"total": {
"filter": {
"range": {
"date": {
"gte": "your_date_mx",
"lte": "your_date_min"
}
}
},
"aggs": {
"NAME": {
"terms": {
"field": "name",
"size": 10
}
}
}
}
}
}
案例2)在这种情况下,当我们在查询级别添加日期范围过滤器时,您的文档计数和聚合都将被过滤日期范围。
{
"query": {
"query_string": {
"query": "country:\"SL\""
},
"bool": {
"must": [
{
"range": {
"date": {
"gte": "your_date_mx",
"lte": "your_date_mic"
}
}
}
]
}
},
"aggs": {
"toal": {
"terms": {
"field": "name",
"size": 10
}
}
}
}
因此,向聚合添加过滤器将仅影响aggs计数。 编辑 - Approach1)使用groovy脚本尝试连接字符串并将其解析为整数,然后与输入日期进行比较。
{
"query": {
"bool": {
"must": [
{}
],
"filter": {
"script": {
"script": {
"inline": "(doc['year'].value + doc['month'].value + doc['date'].value).toInteger() > 19910701",
"params": {
"param1": 19911122
}
}
}
}
}
}
}
确保将索引日期(或月份)索引为单个数字(如6)作为06
2)方法2 - 将字符串解析为确切的日期(首选)
{
"query": {
"bool": {
"must": [
{}
],
"filter": {
"script": {
"script": {
"inline": "Date.parse('dd-MM-yyyy',doc['date'].value +'-'+ doc['month'].value +'-'+ doc['year'].value).format('dd-MM-yyyy') > param1",
"params": {
"param1": "04-05-1991"
}
}
}
}
}
}
}
第二种方法是更好的方法,因为您不必担心为每个字段(日期,月份,日期)维护字符串,以便稍后解析为适当的int进行比较。