【问题标题】:Trouble using date_range in Elastic Search; aggregations not working在 Elastic Search 中使用 date_range 时遇到问题;聚合不起作用
【发布时间】:2014-08-24 15:56:10
【问题描述】:

我有一个允许多个字段在数据库中搜索记录的表单。它能够按名字、姓氏、位置等进行搜索,但我在向查询中添加日期范围时遇到了麻烦。每条记录都有开始年份和结束年份,我的表单有日期到和从字段。我的代码检查字段中的每个表单是否都已填写,如果是,则附加到查询字符串;一旦查询字符串完成,它就会被传递到 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 bad request 错误。同样,当没有填写年份字段时,它工作得很好。我确定这是我如何格式化查询的问题,但我不确定我做错了什么。另外,有没有更简单的方法可以在不使用聚合的情况下搜索日期范围?有没有一种搜索方法可以放在“查询{”本身而不是在它之后?

【问题讨论】:

  • 请发布您收到的确切错误消息。

标签: datetime search aggregation date-range


【解决方案1】:

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

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

我的问题是假设不能在范围查询中正确读取日期时间对象,但实际上您可以在范围内使用日期时间对象。

【讨论】:

    【解决方案2】:

    如果您尝试按日期范围过滤结果,而您不想使用 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",
              }
            }
          },
        ]}
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-29
      • 2018-01-14
      • 1970-01-01
      • 1970-01-01
      • 2012-07-03
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      相关资源
      最近更新 更多