Elasticsearch geo_shape过滤器没有结果

时间:2015-02-13 11:22:41

标签: elasticsearch nested elasticsearch-geo-shape

我在使用geo_shape过滤器在嵌套位置上过滤时返回结果时遇到问题。

假设我有以下内容:

PUT test/test/_mapping
{
  "properties": {
    "name": {
      "type": "string"
    },
    "gatheringEvent": {
      "properties": {
        "siteCoordinates": {
          "type": "nested",
          "properties": {
            "point": {
              "type": "geo_shape"
            }
          }
        }
      }
    },
    "point": {
      "type": "geo_shape"
    }
  }
}

现在,当我索引以下文档时:

POST test/test/1
{
  "name": "Bird",
  "gatheringEvent.siteCoordinates.point": {
    "type": "point",
    "coordinates": [
      5,
      5
    ]
  },
  "point": {
    "type": "point",
    "coordinates": [
      5,
      5
    ]
  }
}

执行以下查询:(在非嵌套位置使用geo_shape过滤器)

GET test/test/_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "name": "Bird"
        }
      },
      "filter": {
        "geo_shape": {
          "point": {
            "shape": {
              "type": "polygon",
              "coordinates": [
                [
                  [0 ,0 ],
                  [10 ,0],
                  [10,10],
                  [0,10 ],
                  [0 ,0 ]
                ]
              ]
            },
            "relation": "within"
          }
        }
      }
    }
  }
}

按照我的预期给我回复我的文件。

但是在嵌套位置执行geo_shape过滤器时:

GET test/test/_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "name": "Bird"
        }
      },
      "filter": {
        "nested": {
          "path": "gatheringEvent.siteCoordinates",
          "filter": {
            "geo_shape": {
              "gatheringEvent.siteCoordinates.point": {
                "shape": {
                  "type": "polygon",
                  "coordinates": [
                    [
                      [0 ,0 ],
                      [10 ,0],
                      [10,10],
                      [0,10 ],
                      [0 ,0 ]
                    ]
                  ]
                },
                "relation": "within"
              }
            }
          }
        }
      }
    }
  }
}

没有结果..

我还删除了嵌套映射,因为我认为这可能是问题,但只要'point'字段驻留在对象类型字段中,我就没有结果..

对我在这里做错了什么的想法?

感谢。

1 个答案:

答案 0 :(得分:3)

我在这里看到了几个问题:

  • 看起来您需要两级嵌套(除非这是一个错误),因此如果您希望能够在查询中使用nested过滤器,则需要在映射中指定两个级别。
  • 使用嵌套结构索引文档时,不能使用点语法;该语法仅用于查询。如果您在索引文档之前和之后查看映射,您将看到在索引文档时添加了名为"gatheringEvent.siteCoordinates.point"的顶级属性,这可能不是您想要的。

您可以通过几种不同的方式继续进行。这就是我能够让它发挥作用的方式。首先,我修改了您的映射以包含两个嵌套级别,并创建了一个索引,如下所示:

DELETE /test_index

PUT /test_index
{
   "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 0
   }
}

PUT /test_index/doc/_mapping
{
   "properties": {
      "name": {
         "type": "string"
      },
      "gatheringEvent": {
         "type": "nested",
         "properties": {
            "siteCoordinates": {
               "type": "nested",
               "properties": {
                  "point": {
                     "type": "geo_shape"
                  }
               }
            }
         }
      },
      "point": {
         "type": "geo_shape"
      }
   }
}

然后我使用适当的结构索引您的文档以进行两级嵌套:

POST /test_index/doc/1
{
   "name": "Bird",
   "gatheringEvent": [
      {
         "siteCoordinates": [
            {
               "point": {
                  "type": "point",
                  "coordinates": [5, 5]
               }
            }
         ]
      }
   ],
   "point": {
      "type": "point",
      "coordinates": [5, 5]
   }
}

我还在边界框外添加了第二个文档,作为完整性检查:

POST /test_index/doc/2
{
   "name": "Bird",
   "gatheringEvent": [
      {
         "siteCoordinates": [
            {
               "point": {
                  "type": "point",
                  "coordinates": [6, 11]
               }
            }
         ]
      }
   ],
   "point": {
      "type": "point",
      "coordinates": [6, 11]
   }
}

现在,您的两个查询都按预期工作:

POST /test_index/doc/_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "name": "Bird"
        }
      },
      "filter": {
        "nested": {
          "path": "gatheringEvent.siteCoordinates",
          "filter": {
            "geo_shape": {
              "gatheringEvent.siteCoordinates.point": {
                "shape": {
                  "type": "polygon",
                  "coordinates": [
                    [
                      [0, 0],
                      [10, 0],
                      [10, 10],
                      [0, 10],
                      [0, 0]
                    ]
                  ]
                },
                "relation": "within"
              }
            }
          }
        }
      }
    }
  }
}
{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1.6931472,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "1",
            "_score": 1.6931472,
            "_source": {
               "name": "Bird",
               "gatheringEvent": [
                  {
                     "siteCoordinates": [
                        {
                           "point": {
                              "type": "point",
                              "coordinates": [
                                 5,
                                 5
                              ]
                           }
                        }
                     ]
                  }
               ],
               "point": {
                  "type": "point",
                  "coordinates": [
                     5,
                     5
                  ]
               }
            }
         }
      ]
   }
} 

如果你真的只想要一个级别的嵌套,那就更容易了。如果你愿意,我也可以添加该代码,只需询问。

以下是我使用的代码:

http://sense.qbox.io/gist/e61259626d5f8525ee41ce7b049af25089bfb8f6