如何使用Python(Flask)在Elasticsearch中获取最近的地理点

问题描述 投票:0回答:1

我正在遵循 Elasticsearch 使用 Python 和 Flask 的官方教程。我实现了全文匹配搜索,但我想扩展该功能以查找最近的位置。我又从官方文档geo-distance query中找到了。我尝试了查询,但它在我这边不起作用。这是我创建的搜索对象:

from pprint import pprint

from elasticsearch import Elasticsearch
from decouple import config
from managers.home_manager import HomeManager
from schemas.response.home_response import HomeResponseSchema, PinSchema

mapping = {
    "mappings": {
        "properties": {"pin": {"properties": {"location": {"type": "geo_point"}}}}
    }
}


class Search:
    def __init__(self) -> None:
        self.es = Elasticsearch(
            api_key=config("ELASTIC_API_KEY"), cloud_id=config("ELASTIC_CLOUD_ID")
        )
        client_info = self.es.info()
        print("Connected to Elasticsearch!")
        pprint(client_info.body)

    def create_index(self):
        self.es.indices.delete(index="real_estate_homes", ignore_unavailable=True)
        self.es.indices.create(index="real_estate_homes", body=mapping)

    def insert_document(self, document):
        return self.es.index(index="real_estate_homes", body=document)

    def insert_documents(self, documents):
        operations = []
        for document in documents:
            operations.append({"index": {"_index": "real_estate_homes"}})
            operations.append(document)
        return self.es.bulk(operations=operations)

    def reindex_homes(self):
        self.create_index()
        homes = HomeManager.select_all_homes()
        pins = []
        for home in homes:
            pin = {
                "location": {"lat": float(home.latitude), "lon": float(home.longitude)}
            }
            pins.append(pin)
        
        return self.insert_documents(pins)

    def search(self, **query_args):
        return self.es.search(index="real_estate_homes", **query_args)


es = Search()

我想提一下,我尝试使用 PinSchema 对象转储 json 文件。

这是带有查询的代码:

from flask_restful import Resource

from managers.home_manager import HomeManager
from search import es
from schemas.response.home_response import HomeResponseSchema


class ElasticResource(Resource):
    def get(self, home_id):
        print(home_id)
        home = HomeManager.select_home_by_id(home_id)
        geo_query = es.search(
            body={
                "query": {
                    "bool": {
                        "must": {"match_all": {}},
                        "filter": {
                            "geo_distance": {
                                "distance": "2000km",
                                "pin.location": {"lat": 43, "lon": 27},
                            }
                        },
                    }
                }
            }
        )
        print(geo_query)
        result = es.search(
            query={
                "bool": {
                    "must": {"match": {"city": {"query": home.city}}},
                    "must_not": {"match": {"id": {"query": home.id}}},
                }
            }
        )
        print(result["hits"]["hits"])
        if len(result["hits"]["hits"]) == 0:
            return "No results."
        suggested_homes = [
            suggested_home["_source"] for suggested_home in result["hits"]["hits"]
        ]
        resp_schema = HomeResponseSchema()
        return resp_schema.dump(suggested_homes, many=True), 200

有人可以帮我找到问题并接收匹配吗?

我尝试在 StackOverflow 中寻找解决方案,但也没有成功。

python elasticsearch flask geolocation
1个回答
0
投票

我仔细查看了发送到 Elasticsearch 的数据。我可以看到字典引脚的构造是错误的:

 def reindex_homes(self):
    self.create_index()
    homes = HomeManager.select_all_homes()
    pins = []
    for home in homes:
        pin = {
            "pin": {"location": {"lat": float(home.latitude), "lon": float(home.longitude)}}
        }
        pins.append(pin)
    
    return self.insert_documents(pins)
© www.soinside.com 2019 - 2024. All rights reserved.