python - Django Haystack Elasticsearch : order by position of matched term

标签 python django elasticsearch django-haystack

我目前正在 Django 上构建 webapp,它使用 Haystack 和 ElasticSearch 来实现搜索。我成功地设置了它,但现在我正在努力实现正确的搜索结果顺序。

我使用默认的 es 后端实现,搜索的文档包括游戏名称、俄罗斯游戏名称和描述:

text = indexes.CharField(document=True, use_template=True)

#Document
{{ object.name }}
{{ object.name_ru }}
{{ object.description }}

我从以下查询中获得 SearchResult:

sqs=SearchQuerySet().models(Game).load_all()\
                                 .filter(content__startswith=query)

结果是预期的结果,而不是期望的结果。例如,如果我按“adv”搜索,结果是:

  1. 使命召唤:高级 war
  2. 胖公主历险记
  3. 冒险时间:芬恩和 jack 调查
  4. Fairy Fencer F: Advent Dark Force

我想要的是按游戏名称中单词(以查询开头)的位置排序的结果,因此示例结果应如下所示:

  1. 冒险时间:芬恩和 jack 调查
  2. 胖公主历险记
  3. 使命召唤:高级 war
  4. Fairy Fencer F: Advent Dark Force

拜托,有人可以指出我如何实现这一目标。提前致谢!

更新!!! 请参阅下面我的解决方案。

最佳答案

解决了。 部分答案在此处找到:stackoverflow.com/questions/27538766/scoring-by-term-position-in-elasticsearch - 解释了如何重写评分以考虑术语位置并构建查询以按该分数排序。

结果是,要使其与 Django-Haystack 一起使用,您需要覆盖 Haystack 提供的 Elasticsearch Backend 和 SearchQuerySet。下面是我对此的实现。

首先,Haystack需要的是:

  1. 像这样生成正确的映射:

    "text" : {            
        "type" : "string",
        "index_options" : "offsets",
        "index_analyzer" : "edgengram_analyzer",
        "search_analyzer" : "standard_search"
      }
    

    当“index_options”设置为“offsets”时——术语偏移量保存在索引中,以便我们稍后在评分脚本中检索它。

  2. 构建按更新分数排序的查询。我的查询如下所示:

    {"query":{
             "match_phrase_prefix" : {"text" : text}
             },
     "sort": {
              "_script": {
                        "script_file": "score_script",
                        "type":"number",
                        "order": "asc",
                        "params": {"q": text}
                         }
             }
    }
    

    提供更新分数的脚本文件“score_script”如下所示:

    termInfo=_index["text"].get(q,_OFFSETS | _CACHE);
    for(pos in termInfo)
    {
    return _score+pos.startOffset
    };
    

所以首先要做的是。为了构建正确的映射,我们需要覆盖 Haystack 提供的 ElasticSearch 后端,这样我们就可以传递自定义参数,如“index_options”。我的实现基于 elasticstack——允许为每个字段指定自定义分析器的项目,如下所示:

    text = CharField(document=True, use_template=True,
        analyzer='stop')

这是我对 elasticstack 可配置后端的定制——gist.github.com/GrigoriyMikhalkin/f76be703bc53380986a0#file-backend-py。它添加了 'add' 参数,该参数接受形式字典 -- {parameter: value}。示例:

    text = CharField(document=True, use_template=True,
                 analyzer="edgengram_analyzer",\
                 add={"search_analyzer":"standard_search",
                      "index_options":"offsets"})

要使用它,您需要像这样覆盖旅游项目的 settings.py 中的 HAYSTACK_CONNECTIONS 变量:

    HAYSTACK_CONNECTIONS = {
    "default":{
       "ENGINE":
            "base.search_backend.backend.ConfigurableElasticSearchEngine",
       "URL": os.getenv("ELASTICSEARCH_URL", "http://127.0.0.1:9200/"),
       "INDEX_NAME": "haystack",
}

有关详细信息,请参阅 elasticstack 文档。

下一步是构建正确的查询。它由两部分组成。首先,您需要创建重新评分的脚本(如上面的脚本)并将其放置在 ES 的/config/scripts/目录中。

下一步是覆盖 Haystack 提供的默认 SearchQuerySet。我的实现受到这篇博文的启发: http://www.stamkracht.com/extending-haystacks-elasticsearch-backend/

我的实现 (gist.github.com/GrigoriyMikhalkin/f76be703bc53380986a0#file-query-py) 将 custom_search 方法添加到 SearchQuerySet。可以这样使用:

    sqs = ConfigurableSearchQuerySet().models(Game).load_all()\
                                      .filter(content__startswith=q)\
                                      .custom_search(search_text=q)

My custom ElasticSearch Backend.

关于python - Django Haystack Elasticsearch : order by position of matched term,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33789024/

相关文章:

elasticsearch - 模糊搜索词组/多个术语

c# - 通过Nest中的SearchRequest类设置索引名称

python - 我想使用 rss 实现基于树的回归模型

python - 在 PyCharm 中的远程解释器上运行远程脚本

python - 在 Django Celery 结果中使用临时文件

python - django - 获取用于调用 django View 的确切 GET url(包括参数)

ruby-on-rails - 使用 geo_polygon 过滤器获取轮胎/ Elasticsearch 中用户定义的多边形内的所有属性

python - 如何比较两个 numpy 字符串数组与 "in"运算符以使用数组广播获取 bool 数组?

python - 基于匹配对象的字符串替换 (Python)

html - 为什么 CSS 文件不改变 Django 元素中 HTML 标签的颜色?