Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›Query DSL ›Geo queries

Запрос по геоформе

Фильтровать документы, индексированные с помощью типа geo_shape или типа geo_point.

Запрос geo_shape использует тот же индекс, что и отображение geo_shape или geo_point, для поиска документов, у которых форма связана с формой запроса с использованием заданного пространственного отношения: пересекается, содержится, находится внутри или не пересекается.

Запрос поддерживает два способа определения формы запроса: либо путем предоставления определения всей формы, либо путем ссылки на имя формы, предварительно проиндексированной в другом индексе. Оба формата определены ниже с примерами.

Определение формы в запросе

Аналогично типу geo_point, запрос geo_shape использует GeoJSON для представления форм.

Рассмотрим следующий индекс с полями местоположений, как geo_shape:

resp = client.indices.create(
    index="example",
    mappings={
        "properties": {
            "location": {
                "type": "geo_shape"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="example",
    refresh=True,
    document={
        "name": "Wind & Wetter, Berlin, Germany",
        "location": {
            "type": "point",
            "coordinates": [
                13.400544,
                52.530286
            ]
        }
    },
)
print(resp1)
response = client.indices.create(
  index: 'example',
  body: {
    mappings: {
      properties: {
        location: {
          type: 'geo_shape'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'example',
  refresh: true,
  body: {
    name: 'Wind & Wetter, Berlin, Germany',
    location: {
      type: 'point',
      coordinates: [
        13.400544,
        52.530286
      ]
    }
  }
)
puts response
const response = await client.indices.create({
  index: "example",
  mappings: {
    properties: {
      location: {
        type: "geo_shape",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "example",
  refresh: "true",
  document: {
    name: "Wind & Wetter, Berlin, Germany",
    location: {
      type: "point",
      coordinates: [13.400544, 52.530286],
    },
  },
});
console.log(response1);
PUT /example
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_shape"
      }
    }
  }
}

POST /example/_doc?refresh
{
  "name": "Wind & Wetter, Berlin, Germany",
  "location": {
    "type": "point",
    "coordinates": [ 13.400544, 52.530286 ]
  }
}

Следующий запрос найдет точку с использованием расширения GeoJSON Elasticsearch’a envelope:

resp = client.search(
    index="example",
    query={
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": {
                "geo_shape": {
                    "location": {
                        "shape": {
                            "type": "envelope",
                            "coordinates": [
                                [
                                    13,
                                    53
                                ],
                                [
                                    14,
                                    52
                                ]
                            ]
                        },
                        "relation": "within"
                    }
                }
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'example',
  body: {
    query: {
      bool: {
        must: {
          match_all: {}
        },
        filter: {
          geo_shape: {
            location: {
              shape: {
                type: 'envelope',
                coordinates: [
                  [
                    13,
                    53
                  ],
                  [
                    14,
                    52
                  ]
                ]
              },
              relation: 'within'
            }
          }
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "example",
  query: {
    bool: {
      must: {
        match_all: {},
      },
      filter: {
        geo_shape: {
          location: {
            shape: {
              type: "envelope",
              coordinates: [
                [13, 53],
                [14, 52],
              ],
            },
            relation: "within",
          },
        },
      },
    },
  },
});
console.log(response);
GET /example/_search
{
  "query": {
    "bool": {
      "must": {
        "match_all": {}
      },
      "filter": {
        "geo_shape": {
          "location": {
            "shape": {
              "type": "envelope",
              "coordinates": [ [ 13.0, 53.0 ], [ 14.0, 52.0 ] ]
            },
            "relation": "within"
          }
        }
      }
    }
  }
}

Этот запрос может аналогичным образом быть запрошен по полям geo_point.

resp = client.indices.create(
    index="example_points",
    mappings={
        "properties": {
            "location": {
                "type": "geo_point"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="example_points",
    id="1",
    refresh=True,
    document={
        "name": "Wind & Wetter, Berlin, Germany",
        "location": [
            13.400544,
            52.530286
        ]
    },
)
print(resp1)
response = client.indices.create(
  index: 'example_points',
  body: {
    mappings: {
      properties: {
        location: {
          type: 'geo_point'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'example_points',
  id: 1,
  refresh: true,
  body: {
    name: 'Wind & Wetter, Berlin, Germany',
    location: [
      13.400544,
      52.530286
    ]
  }
)
puts response
const response = await client.indices.create({
  index: "example_points",
  mappings: {
    properties: {
      location: {
        type: "geo_point",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "example_points",
  id: 1,
  refresh: "true",
  document: {
    name: "Wind & Wetter, Berlin, Germany",
    location: [13.400544, 52.530286],
  },
});
console.log(response1);
PUT /example_points
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      }
    }
  }
}

PUT /example_points/_doc/1?refresh
{
  "name": "Wind & Wetter, Berlin, Germany",
  "location": [13.400544, 52.530286]
}

Используя тот же запрос, возвращаются документы с соответствующими полями geo_point.

resp = client.search(
    index="example_points",
    query={
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": {
                "geo_shape": {
                    "location": {
                        "shape": {
                            "type": "envelope",
                            "coordinates": [
                                [
                                    13,
                                    53
                                ],
                                [
                                    14,
                                    52
                                ]
                            ]
                        },
                        "relation": "intersects"
                    }
                }
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'example_points',
  body: {
    query: {
      bool: {
        must: {
          match_all: {}
        },
        filter: {
          geo_shape: {
            location: {
              shape: {
                type: 'envelope',
                coordinates: [
                  [
                    13,
                    53
                  ],
                  [
                    14,
                    52
                  ]
                ]
              },
              relation: 'intersects'
            }
          }
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "example_points",
  query: {
    bool: {
      must: {
        match_all: {},
      },
      filter: {
        geo_shape: {
          location: {
            shape: {
              type: "envelope",
              coordinates: [
                [13, 53],
                [14, 52],
              ],
            },
            relation: "intersects",
          },
        },
      },
    },
  },
});
console.log(response);
GET /example_points/_search
{
  "query": {
    "bool": {
      "must": {
        "match_all": {}
      },
      "filter": {
        "geo_shape": {
          "location": {
            "shape": {
              "type": "envelope",
              "coordinates": [ [ 13.0, 53.0 ], [ 14.0, 52.0 ] ]
            },
            "relation": "intersects"
          }
        }
      }
    }
  }
}
{
  "took" : 17,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "example_points",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name": "Wind & Wetter, Berlin, Germany",
          "location": [13.400544, 52.530286]
        }
      }
    ]
  }
}

Предварительно проиндексированная форма

Запрос также поддерживает использование формы, которая уже была проиндексирована в другом индексе. Это особенно полезно, когда у вас есть предварительно определенный список форм, и вы хотите ссылаться на список с помощью логического имени (например, Новая Зеландия), а не каждый раз предоставлять координаты. В этой ситуации достаточно указать:

  • id — Идентификатор документа, содержащего предварительно проиндексированную форму.
  • index — Название индекса, в котором находится предварительно проиндексированная форма. По умолчанию — shapes.
  • path — Поле, указанное как путь, содержащий предварительно проиндексированную форму. По умолчанию — shape.
  • routing — Маршрутизация документа формы, если требуется.

Следующий пример использования фильтра с предварительно проиндексированной формой:

resp = client.indices.create(
    index="shapes",
    mappings={
        "properties": {
            "location": {
                "type": "geo_shape"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="shapes",
    id="deu",
    document={
        "location": {
            "type": "envelope",
            "coordinates": [
                [
                    13,
                    53
                ],
                [
                    14,
                    52
                ]
            ]
        }
    },
)
print(resp1)

resp2 = client.search(
    index="example",
    query={
        "bool": {
            "filter": {
                "geo_shape": {
                    "location": {
                        "indexed_shape": {
                            "index": "shapes",
                            "id": "deu",
                            "path": "location"
                        }
                    }
                }
            }
        }
    },
)
print(resp2)
response = client.indices.create(
  index: 'shapes',
  body: {
    mappings: {
      properties: {
        location: {
          type: 'geo_shape'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'shapes',
  id: 'deu',
  body: {
    location: {
      type: 'envelope',
      coordinates: [
        [
          13,
          53
        ],
        [
          14,
          52
        ]
      ]
    }
  }
)
puts response

response = client.search(
  index: 'example',
  body: {
    query: {
      bool: {
        filter: {
          geo_shape: {
            location: {
              indexed_shape: {
                index: 'shapes',
                id: 'deu',
                path: 'location'
              }
            }
          }
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "shapes",
  mappings: {
    properties: {
      location: {
        type: "geo_shape",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "shapes",
  id: "deu",
  document: {
    location: {
      type: "envelope",
      coordinates: [
        [13, 53],
        [14, 52],
      ],
    },
  },
});
console.log(response1);

const response2 = await client.search({
  index: "example",
  query: {
    bool: {
      filter: {
        geo_shape: {
          location: {
            indexed_shape: {
              index: "shapes",
              id: "deu",
              path: "location",
            },
          },
        },
      },
    },
  },
});
console.log(response2);
PUT /shapes
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_shape"
      }
    }
  }
}

PUT /shapes/_doc/deu
{
  "location": {
    "type": "envelope",
    "coordinates" : [[13.0, 53.0], [14.0, 52.0]]
  }
}

GET /example/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_shape": {
          "location": {
            "indexed_shape": {
              "index": "shapes",
              "id": "deu",
              "path": "location"
            }
          }
        }
      }
    }
  }
}

Пространственные отношения

Ниже приведен полный список операторов пространственных отношений, доступных при поиске по гео-полю:

  • INTERSECTS — (по умолчанию) Вернуть все документы, у которых поле geo_shape или geo_point пересекается с геометрией запроса.
  • DISJOINT — Вернуть все документы, у которых поле geo_shape или geo_point не имеет общих точек с геометрией запроса.
  • WITHIN — Вернуть все документы, у которых поле geo_shape или geo_point находится внутри геометрии запроса. Линейные геометрии не поддерживаются.
  • CONTAINS — Вернуть все документы, у которых поле geo_shape или geo_point содержит геометрию запроса.

Игнорировать неотображенные

При установке в true опция ignore_unmapped проигнорирует неотображенное поле и не сопоставит никакие документы для данного запроса. Это может быть полезно при поиске по нескольким индексам, которые могут иметь различные отображения. При установке в false (значение по умолчанию) запрос выбросит исключение, если поле не отображается.

Примечания

  • Когда данные индексируются в поле geo_shape в качестве массива форм, массивы обрабатываются как одна форма. По этой причине следующие запросы эквивалентны.
resp = client.index(
    index="test",
    id="1",
    document={
        "location": [
            {
                "coordinates": [
                    46.25,
                    20.14
                ],
                "type": "point"
            },
            {
                "coordinates": [
                    47.49,
                    19.04
                ],
                "type": "point"
            }
        ]
    },
)
print(resp)
response = client.index(
  index: 'test',
  id: 1,
  body: {
    location: [
      {
        coordinates: [
          46.25,
          20.14
        ],
        type: 'point'
      },
      {
        coordinates: [
          47.49,
          19.04
        ],
        type: 'point'
      }
    ]
  }
)
puts response
const response = await client.index({
  index: "test",
  id: 1,
  document: {
    location: [
      {
        coordinates: [46.25, 20.14],
        type: "point",
      },
      {
        coordinates: [47.49, 19.04],
        type: "point",
      },
    ],
  },
});
console.log(response);
PUT /test/_doc/1
{
  "location": [
    {
      "coordinates": [46.25,20.14],
      "type": "point"
    },
    {
      "coordinates": [47.49,19.04],
      "type": "point"
    }
  ]
}
resp = client.index(
    index="test",
    id="1",
    document={
        "location": {
            "coordinates": [
                [
                    46.25,
                    20.14
                ],
                [
                    47.49,
                    19.04
                ]
            ],
            "type": "multipoint"
        }
    },
)
print(resp)
response = client.index(
  index: 'test',
  id: 1,
  body: {
    location: {
      coordinates: [
        [
          46.25,
          20.14
        ],
        [
          47.49,
          19.04
        ]
      ],
      type: 'multipoint'
    }
  }
)
puts response
const response = await client.index({
  index: "test",
  id: 1,
  document: {
    location: {
      coordinates: [
        [46.25, 20.14],
        [47.49, 19.04],
      ],
      type: "multipoint",
    },
  },
});
console.log(response);
PUT /test/_doc/1
{
  "location":
    {
      "coordinates": [[46.25,20.14],[47.49,19.04]],
      "type": "multipoint"
    }
}
  • Запрос geo_shape предполагает, что поля geo_shape используют значение по умолчанию orientation RIGHT (против часовой стрелки). См. ориентацию многоугольников.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/query-dsl-geo-shape-query.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API