python - Django haystack LocationField 在 elasticsearch 中创建为字符串而不是 geo_point

标签 python django elasticsearch django-haystack

我将 django 1.8.9、django-rest-framework、django-haystack 与 Elasticsearch 一起使用,并试图让 LocationField 正常工作,索引已创建,但类型始终是 string而不是 geo_point,所以显然没有地理搜索工作。

设置.py:

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',
)

要求.txt:

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

search_indexes.py:

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

MyModel 的 get_location 属性:

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

创建的 elasticsearch 索引(对格式感到抱歉!):

{  
   "myindex":{  
      "mappings":{  
         "modelresult":{  
            "properties":{  
               "created":{  
                  "type":"date",
                  "format":"strict_date_optional_time||epoch_millis"
               },
               "description":{  
                  "type":"string"
               },
               "django_ct":{  
                  "type":"string"
               },
               "django_id":{  
                  "type":"string"
               },
               "id":{  
                  "type":"string"
               },
               "location":{  
                  "type":"string"
               },
               "text":{  
                  "type":"string"
               }
            }
         }
      }
   }
}

有人有什么想法吗?感觉它是 django、django-haystack 和 elasticsearch 之间的版本组合,效果不佳,但我似乎无法使任何组合正常工作。

最佳答案

好的,我已经弄清楚问题是什么了: 在 Elasticsearch 2.0 中,元数据发生了变化,其中之一是 boost 已被删除:https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking_20_mapping_changes.html#migration-meta-fields

通过elasticsearch/transport.py回溯,PUT请求到http://127.0.0.1:9200/myindex/_mapping/modelresult包括 "_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 部分

关于python - Django haystack LocationField 在 elasticsearch 中创建为字符串而不是 geo_point,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35443179/

相关文章:

python - Scapy - 我怎样才能隐藏 sendp\sr1 的报告并只得到最终的报告?

Django,在模型中按函数过滤 Q 对象

elasticsearch - Kibana 中的自定义 X 轴

python - 在Python的Kivy中用图像填充GridLayout

python - 正则表达式:替换文本,除非它位于引号之间

python - 在 Pillow 中打开和加载图像时出现 "Too many open files"错误

django - 如何从 View 中生成 Django 管理站点中特定项目的 url?

python - django View 从另一个应用程序渲染到模板

c# - 运算符 '??' 不能应用于 IQueryContainer 类型的操作数和 lambda 表达式

bash - 无法在 Azure Powershell 中键入密码