Django haystack在弹性搜索中将LocationField创建为字符串而不是geo_point

时间:2016-02-16 21:18:21

标签: python django elasticsearch django-haystack

我正在使用django 1.8.9,django-rest-framework,django-haystack和Elasticsearch,并且我正在尝试使LocationField工作,但是创建了索引但是类型总是string而不是{ {1}},显然没有地理搜索功能。

settings.py:

geo_point

requirements.txt:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.gis',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'django_extensions',
    'elasticsearch',
    'rest_framework',
    'haystack',
)

search_indexes.py:

Django==1.8.9
django-appconf==1.0.1
django-compressor==1.6
django-extensions==1.6.1
django-filter==0.11.0
django-haystack==2.4.1
djangorestframework==3.3.1
djangorestframework-jwt==1.7.2
ecdsa==0.13
elasticsearch==2.2.0
Fabric==1.10.2
future==0.15.2
geopy==1.11.0
gunicorn==19.4.1
Markdown==2.6.5
paramiko==1.16.0
psycopg2==2.6.1
pycrypto==2.6.1
PyJWT==1.4.0
python-dateutil==2.4.2
python-memcached==1.57
setproctitle==1.1.9
six==1.10.0
urllib3==1.14

MyModel上的get_location属性:

from haystack import indexes
from blah.api.models import MyModel


class MyIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    description = indexes.CharField(model_attr='description')
    location = indexes.LocationField(model_attr='get_location')
    created = indexes.DateTimeField(model_attr='created')

    def get_model(self):
        return MyModel

创建了elasticsearch索引(抱歉格式化!):

from haystack.utils.geo import Point
def get_location(self):
    return Point(self.lng, self.lat)

有没有人有任何想法?感觉它是django,django-haystack和elasticsearch之间的版本组合不能很好地发挥,但我似乎无法让任何组合工作。

2 个答案:

答案 0 :(得分:5)

好的,我已经弄清楚问题是什么: 在Elasticsearch 2.0中,有元数据更改,其中一个已被删除boost

追溯到elasticsearch/transport.py,对https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking_20_mapping_changes.html#migration-meta-fields的PUT请求包括“_boost”:{“name”:“boost”,“null_value”:1.0}在正文中。

跟踪调用并将它们表示为CURL:

创建索引

curl -X PUT -d '{"settings": {"analysis": {"filter": {"haystack_edgengram": {"max_gram": 15, "type": "edgeNGram", "min_gram": 2}, "haystack_ngram": {"max_gram": 15, "type": "nGram", "min_gram": 3}}, "tokenizer": {"haystack_ngram_tokenizer": {"max_gram": 15, "type": "nGram", "min_gram": 3}, "haystack_edgengram_tokenizer": {"max_gram": 15, "type": "edgeNGram", "side": "front", "min_gram": 2}}, "analyzer": {"edgengram_analyzer": {"filter": ["haystack_edgengram", "lowercase"], "type": "custom", "tokenizer": "standard"}, "ngram_analyzer": {"filter": ["haystack_ngram", "lowercase"], "type": "custom", "tokenizer": "standard"}}}}}' http://127.0.0.1:9200/myindex

失败请求

curl -X PUT -d '{"modelresult": {"_boost": {"name": "boost", "null_value": 1.0}, "properties": {"django_id": {"include_in_all": false, "index": "not_analyzed", "type": "string"}, "description": {"type": "string", "analyzer": "snowball"}, "created": {"type": "date"}, "text": {"type": "string", "analyzer": "snowball"}, "django_ct": {"include_in_all": false, "index": "not_analyzed", "type": "string"}, "location": {"type": "geo_point"}}}}' http://127.0.0.1:9200/myindex/_mapping/modelresult

更改为此作品

curl -X PUT -d '{"modelresult": {"properties": {"django_id": {"include_in_all": false, "index": "not_analyzed", "type": "string"}, "description": {"type": "string", "analyzer": "snowball"}, "created": {"type": "date"}, "text": {"type": "string", "analyzer": "snowball"}, "django_ct": {"include_in_all": false, "index": "not_analyzed", "type": "string"}, "location": {"type": "geo_point"}}}}' http://127.0.0.1:9200/myindex/_mapping/modelresult

所以,python修复 在haystack / backends / elasticsearch_backend.py中,从第137-140行的current_mapping注释掉boost部分

答案 1 :(得分:0)

可能它不起作用,因为get_location不是MyModel上的字段。 也许您可以通过添加@property装饰器来避免将位置创建为字段,如下所示:

from haystack.utils.geo import Point

@property
def get_location(self):
    return Point(self.lng, self.lat)

编辑:这看起来不会解决问题。你就像它在文档中一样。