【问题标题】:filter range date elasticsearch过滤范围日期弹性搜索
【发布时间】:2014-09-07 00:46:30
【问题描述】:

这就是我的数据的样子

{
  "name": "thename",
  "openingTimes": {
    "monday": [
      {
        "start": "10:00",
        "end": "14:00"
      },
      {
        "start": "19:00",
        "end": "02:30"
      }
    ]
  }
}

我想查询这个文档说,opened on monday between 13:00 and 14:00
我试过这个过滤器,但它没有返回我的文档:

{
  "filter": {
    "range": {
      "openingTimes.monday.start": {
        "lte": "13:00"
      },
      "openingTimes.monday.end": {
        "gte": "14:00"
      }
    }
  }
}

如果我简单地说opened on monday at 13:00,它可以工作:

{
  "filter": {
    "range": {
      "openingTimes.monday.start": {
        "lte": "13:00"
      }
    }
  }
}

甚至closing on monday from 14:00,也可以:

{
  "filter": {
    "range": {
      "openingTimes.monday.start": {
        "gte": "14:00"
      }
    }
  }
}

但是将它们结合起来并没有给我任何东西。我怎样才能设法创建过滤器含义opened on monday between 13:00 and 14:00

编辑

这就是我映射openingTime 字段的方式

{
  "properties": {
    "monday": {
      "type": "nested",
      "properties": {
        "start": {"type": "date","format": "hour_minute"},
        "end": {"type": "date","format": "hour_minute"}
      }
    }
  }
}

解决方案 (@DanTuffery)

根据@DanTuffery 的回答,我将过滤器更改为他的(效果很好),并添加了openingTime 属性的类型定义。

作为记录,我使用以下 gems 通过 Ruby-on-Rails 使用 elasticsearch 作为我的主数据库:

gem 'elasticsearch-rails', git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
gem 'elasticsearch-model', git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
gem 'elasticsearch-persistence', git: 'git://github.com/elasticsearch/elasticsearch-rails.git', require: 'elasticsearch/persistence/model'

以下是我的 openingTime 属性的映射:

attribute :openingTimes, Hash,    mapping: {
                                    type: :object,
                                    properties: {
                                      monday:     {
                                        type: :nested,
                                        properties: {
                                          start:{type: :date, format: 'hour_minute'},
                                          end:  {type: :date, format: 'hour_minute'}
                                        }
                                      },
                                      tuesday:     {
                                        type: :nested,
                                        properties: {
                                          start:{type: :date, format: 'hour_minute'},
                                          end:  {type: :date, format: 'hour_minute'}
                                        }
                                      },
                                      ...
                                      ...
                                    }
                                  }

这是我实现他的过滤器的方法:

def self.openedBetween startTime, endTime, day
  self.search filter: {
                nested: {
                  path: "openingTimes.#{day}",
                  filter: {
                    bool: {
                      must: [
                        {range: {"openingTimes.#{day}.start"=> {lte: startTime}}},
                        {range: {"openingTimes.#{day}.end"  => {gte: endTime}}}
                      ]
                    }
                  }
                }
              }
end

【问题讨论】:

    标签: date filter elasticsearch range


    【解决方案1】:

    首先在顶层使用openingTimes 对象创建您的映射。

    /PUT http://localhost:9200/demo/test/_mapping
    {
      "test": {
        "properties": {
          "openingTimes": {
            "type": "object",
            "properties": {
              "monday": {
                "type": "nested",
                "properties": {
                  "start": {
                    "type": "date",
                    "format": "hour_minute"
                  },
                  "end": {
                    "type": "date",
                    "format": "hour_minute"
                  }
                }
              }
            }
          }
        }
      }
    }
    

    索引您的文档

    /POST http://localhost:9200/demo/test/1
    {
      "name": "thename",
      "openingTimes": {
        "monday": [
          {
            "start": "10:00",
            "end": "14:00"
          },
          {
            "start": "19:00",
            "end": "02:30"
          }
        ]
      }
    }
    

    使用嵌套过滤器查询,您可以在布尔范围查询中使用startend 字段搜索文档:

    /POST http://localhost:9200/demo/test/_search
    {
      "query": {
        "filtered": {
          "query": {
            "match_all": {}
          },
          "filter": {
            "nested": {
              "path": "openingTimes.monday",
              "filter": {
                "bool": {
                  "must": [
                    {
                      "range": {
                        "openingTimes.monday.start": {
                          "lte": "13:00"
                        }
                      }
                    },
                    {
                      "range": {
                        "openingTimes.monday.end": {
                          "gte": "14:00"
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
    

    【讨论】:

    • 你的过滤器工作得很好,我自己永远不会找到它。我根据您在编辑中的回答添加了我对代码所做的更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多