术语和范围在elasticsearch查询中一起过滤

tug*_*erk 3 elasticsearch

在我的eleasticsearch索引中,我有两个索引如下的文档:

POST dyn-props/item
{
    "name": "bar foo",
    "properties": [
        {
            "type": "foo",
            "value": 1.45
        },

        {
            "type": "bar",
            "value": 256.34
        },

        {
            "type": "foobar",
            "value": 43.43
        }
    ]
}

POST dyn-props/item
{
    "name": "foo bar",
    "properties": [
        {
            "type": "foo",
            "value": 33.34
        },

        {
            "type": "bar",
            "value": 22.23
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

在此项类型上,我想查询具有值大于10的foo属性的项.我可以使用以下查询过滤掉具有类型为foo的属性的项目的结果:

POST dyn-props/item/_search
{
   "query": {
      "filtered": {
         "query": {
            "match_all": {}
         },
         "filter": {
            "term": {
               "properties.type": "foo"
            }
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

但我不知道如何应用范围过滤器的价值.任何的想法?

编辑:

发出以下查询会给出错误的结果:

POST dyn-props/item/_search
{
   "query": {
      "filtered": {
         "query": {
            "match_all": {}
         },
         "filter": {
           "bool": {
             "must": [
               {
                  "term": {
                     "properties.type": "foo"
                  }
               },

                {
                   "range": {
                      "properties.value": {
                        "gte" : 10
                      }
                   }
                }
             ]
           }
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

结果:

{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 1,
      "hits": [
         {
            "_index": "dyn-props",
            "_type": "item",
            "_id": "PetPVxwARLOcZqlv28xjpw",
            "_score": 1,
            "_source": {
               "name": "bar foo",
               "properties": [
                  {
                     "type": "foo",
                     "value": 1.45
                  },
                  {
                     "type": "bar",
                     "value": 256.34
                  },
                  {
                     "type": "foobar",
                     "value": 43.43
                  }
               ]
            }
         },
         {
            "_index": "dyn-props",
            "_type": "item",
            "_id": "KqOTXcC9RG6FzPsDDDs8Hw",
            "_score": 1,
            "_source": {
               "name": "foo bar",
               "properties": [
                  {
                     "type": "foo",
                     "value": 33.34
                  },
                  {
                     "type": "bar",
                     "value": 22.23
                  }
               ]
            }
         }
      ]
   }
}
Run Code Online (Sandbox Code Playgroud)

tug*_*erk 5

找到了答案.这篇文章帮了很多:ElasticSearch - 嵌套映射和过滤器

更改了类型的映射:

PUT dyn-props
{
    "mappings": {
         "item": {
                "properties": {
                     "name": {
                            "type": "string"
                     },
                     "properties": {
                            "type": "nested"
                     }
                }
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

通过将属性设置为嵌套类型,我能够维护typevalue字段之间的关联.

最后,我能够为此发出嵌套查询:

POST dyn-props/item/_search
{
   "query": {
      "filtered": {
         "query": {
            "match_all": {}
         },
         "filter": {
            "nested": {
               "path": "properties",
               "filter": {
                  "bool": {
                     "must": [
                        {
                           "term": {
                              "type": "foo"
                           }
                        },
                        {
                           "range": {
                              "value": {
                                 "gte": 10
                              }
                           }
                        }
                     ]
                  }
               }
            }
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

这让我得到了正确的结果:

{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "dyn-props",
            "_type": "item",
            "_id": "CzTL4sseR2GVYtvf-0slVQ",
            "_score": 1,
            "_source": {
               "name": "foo bar",
               "properties": [
                  {
                     "type": "foo",
                     "value": 33.34
                  },
                  {
                     "type": "bar",
                     "value": 22.23
                  }
               ]
            }
         }
      ]
   }
}
Run Code Online (Sandbox Code Playgroud)