麻烦在Elasticsearch中使用日期范围;聚合不起作用

时间:2014-07-03 13:35:40

标签: datetime search aggregation date-range

我有一个表单,允许多个字段搜索数据库中的记录。它可以按名字,姓氏,位置等进行搜索,但是我在查询中添加日期范围时遇到了问题。每个记录都有一个开始年份和结束年份,我的表单包含Date To和From字段。我的代码检查字段中的每个表单是否已填写,如果是,则附加到查询字符串;查询字符串完成后,将其传递给Connection.Post搜索。一切都有效,除了To和From,但是当我添加这些字段时,我得到404错误。

我有一个QueryBuilder方法,用于检查字段并构建查询,以下是它的启动方式:

    string query = "{\"query\": { \"bool\": { \"must\": [ ";

    bool emptyQ = true;

以下是first_name部分,例如:

        if (!String.IsNullOrWhiteSpace(q.Name.First))
        {
            if (exact == true)
            {
                query += "{ \"match\": { \"first_name\": \"" + q.Name.First + "\" }}";
            }
            else
            {
                // no fuzziness allowed in the search term; how can i fix this? (i.e. Sam -> Samuel, but Isac -\> Isaac)
                query += "{ \"match_phrase_prefix\": { \"first_name\": \"" + q.Name.First + "\"}}";
            }
            emptyQ = false;
        }

以下是无法正常工作的部分:

        bool aggs = false;
        if (q.FromYear != 0 || q.ToYear != DateTime.Now.Year)
        {
            if (emptyQ == false)
            {
                query += "] } }, ";
            }
            if (emptyQ == true)
            {
                query += "{";
            }

            DateTime fromyear = Convert.ToDateTime("01/01/" + q.FromYear.ToString());
            if (q.FromYear == 0)
            {
                fromyear = Convert.ToDateTime("00/00/0000" + q.FromYear.ToString());
            }
            DateTime toyear = Convert.ToDateTime("12/31/" + q.ToYear.ToString());
            query += "\"aggregations\": { \"range\": { \"date_range\": { \"field\": \"start_date\", \"ranges\": [{\"from\": \"" + fromyear + "\"}]}}}";
            query += "{\"range\": { \"date_range\": { \"field\": \"end_date\", \"ranges\": [{\"to\": \"" + toyear +
                     "\"}] }}}}";
            aggs = true;
        }

        if (aggs == false)
        {
            query += " ] } } }";
        }

即。当填写一个或两个日期字段时,查询无效。填写每个字段时,这就是查询构建器返回的内容:

{"query": 
   { "bool": 
      { "must": [ 
         { "match_phrase_prefix": { "first_name": "sam"}}, 
         { "fuzzy": { "last_name": "durand" }}, 
         { "match": { "record_type": { "query": "Baptism", "type": "phrase"} }}, 
         { "fuzzy_like_this": 
             { "fields": [ "city", "region", "county", "country" ], 
               "like_text": "Massachusetts"
             }
         }
      ]}
   }, 
"aggregations": 
   { "range": 
      { "date_range": 
          { "field": "start_date", 
            "ranges": [{"from": "1/1/1600 12:00:00 AM"}]
          }
      }
   },
   {"range": 
      { "date_range": 
          { "field": "end_date", 
            "ranges": [{"to": "12/31/2014 12:00:00 AM"}] 
          }
      }
   }
} 

这给了我一个400错误的请求错误。同样,当年份字段未填写时,它可以正常工作。我确定这是我格式化查询的问题,但我不确定我做错了什么。此外,是否有更简单的方法可以在不使用聚合的情况下搜索日期范围?有没有一种搜索方法可以放在“查询{”本身,而不是在它之后?

2 个答案:

答案 0 :(得分:0)

如果您尝试按日期范围过滤结果,则不希望使用date_range聚合,则需要使用range filter。这会给你更多的东西:

{"query": 
  { "bool": 
    { "must": [ 
      {
        "range" : {
          "start_date" : {
            "gte": "1/1/1600 12:00:00 AM",
          }
        }
      },
      {
        "range" : {
          "end_date" : {
            "lte": 12/31/2014 12:00:00 AM",
          }
        }
      },
    ]}
}

答案 1 :(得分:0)

原来我根本不需要做任何事情,我只是使用了一个简单的范围:

query += "{ \"range\": { \"start_date.year\": { \"gte\": " + fyear + ", \"lte\": " + tyear + "} }}, " +
                     "{ \"range\": { \"end_date.year\": { \"gte\": " + fyear + ", \"lte\": " + tyear + "} }}] } } }, ";

我的问题在于假设在范围查询中无法正确读取datetime对象,但实际上您可以使用范围内的datetime对象。