根据内部数据计数过滤结果

时间:2013-03-20 21:40:41

标签: ruby-on-rails elasticsearch tire

我正在构建一些列表数据的搜索查询。作为搜索的一部分,人们可以要求多个房间可以容纳少量人,即两个房间可容纳2人和3人。

我不确定如何使用过滤器执行此操作。

到目前为止,这是一个缩短的搜索查询。

    {
  "query":{
    "filtered":{
      "query":{
        "match_all":{}
      }
    }
  },
  "filter":{
    "and":
      [
        {
          "term":{
          "status":"live"
          }
        },
        {
          "geo_bounding_box":{
            "location":{
              "top_left":"60.856553, -8.64935719999994",
              "bottom_right":"49.8669688, 1.76270959999999"
              }
            }
          }
        ,{
        "range":{
          "bedrooms":{
            "gte":"2"
            }
          }
        }
      ]
    }
  ,
  "size":10
}

测试数据

{
       "took":1,
       "timed_out":false,
       "_shards":{
          "total":5,
          "successful":5,
          "failed":0
       },
       "hits":{
          "total":3,
          "max_score":1.0,
          "hits":[
             {
                "_index":"listings",
                "_type":"listing",
                "_id":"1",
                "_score":1.0,
                "_source":{
                   "name:":"Listing One",
                   "address1":"Some Street",
                   "bedrooms":2,
                   "city":"A City",
                   "id":1,
                   "refno":"FI451",
                   "user_id":1,
                   "rooms":[
                      {
                         "bathroom":"Shared bathroom with bath",
                         "double_standard":null,
                         "id":5,
                         "single":2,
                         "sleeps":2,
                         "title":"Twinny",
                      },
                      {
                         "bathroom":"Ensuite with bath",
                         "double_king_size":1,
                         "double_standard":1,
                         "id":1,
                         "single":null,
                         "sleeps":2,
                         "title":"Double Ensuite Room",
                      }
                   ]
                }
             },
             {
                "_index":"listings",
                "_type":"listing",
                "_id":"2",
                "_score":1.0,
                "_source":{
                   "name":"Listing Two",
                   "address1":"Some Street",
                   "bedrooms":2,
                   "city":"A City",
                   "id":2,
                   "refno":"BL932",
                   "user_id":1,
                   "rooms":[
                      {
                         "bathroom":"Ensuite with bath",
                         "double_standard":1,
                         "id":4,
                         "single":1,
                         "sleeps":3,
                         "title":"Family Room",
                      },
                      {
                         "bathroom":"Ensuite with shower",
                         "double_standard":1,
                         "id":2,
                         "single":null,
                         "sleeps":2,
                         "title":"Single Room",
                      }
                   ]
                }
             },
             {
                "_index":"listings",
                "_type":"listing",
                "_id":"3",
                "_score":1.0,
                "_source":{
                   "name":"Listing Three",
                   "address1":"Another Address",
                   "bedrooms":1,
                   "city":"Your City",
                   "id":3,
                   "refno":"TE2116",
                   "user_id":1,
                   "rooms":[
                      {
                         "bathroom":"Ensuite with shower",
                         "double_king_size":null,
                         "double_standard":1,
                         "id":3,
                         "single":1,
                         "sleeps":3,
                         "title":"Family Room",
                      }
                   ]
                }
             }
          ]
       }
    }

如果你查看我的数据,我有3个房源,其中两个有多个房间(清单一和二),但只有清单二匹配我的搜索,原因是它有一个房间睡两个,另一个睡三个

是否可以使用elasticsearch执行此查询?

2 个答案:

答案 0 :(得分:1)

如果您想要的是“查找卧室睡2个而另一个卧室睡3个”的所有列表,此查询将起作用。它做了一个很大的假设:您使用的是内部对象,而不是嵌套数据类型。

此查询使用内部对象折叠为单个字段的事实,导致所需字段的“rooms.sleeps”等于[2,3]。由于该字段已折叠为单个数组,因此简单的Terms查询将与它们匹配。当您将执行模式更改为And时,它会强制匹配2和3。

需要注意的是,[2,3,4]的房间也会匹配。

我省略了地理位置和状态部分,因为源文档中未提供该数据。

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      }
    }
  },
  "filter": {
    "and": [
      {
        "range": {
          "bedrooms": {
            "gte": "2"
          }
        }
      },
      {
        "terms": {
          "rooms.sleeps": [2,3],
          "execution": "and"
        }
      }
    ]
  },
  "size": 10
}

答案 1 :(得分:0)

据我所知,filter必须是query元素中filtered的兄弟。请参阅:http://www.elasticsearch.org/guide/reference/query-dsl/filtered-query/

如果你将它与Zach的解决方案结合起来,它应该有效。

{
    "query":
    {
        "filtered":
        {
            "query":
            {
                "match_all":{}
            },
            "filter":
            {
                "put" : "your filter here"
            }
        }
    }
}