Django中的Elasticsearch-按字母顺序排序

时间:2018-11-20 11:14:33

标签: django elasticsearch elasticsearch-dsl

我有以下文档:

@brand.doc_type
class BrandDocument(DocType):

    class Meta:
        model = Brand

    id = IntegerField()
    name = StringField(
        fields={
            'raw': {
                'type': 'keyword',
                'fielddata': True,
            }
        },
    )
    lookup_name = StringField(
        fields={
            'raw': {
                'type': 'string',
            }
        },
    )

,我尝试使用此命令进行查找:

BrandDocument.search().sort({
    'name.keyword': order,
})

问题是我要以区分大小写的方式对结果进行排序,这意味着我得到的是'a', 'A', 'ab', 'AB'而不是'A', 'AB', 'a', 'ab'。如何解决?

编辑,经过一些额外的搜索,我想到了这样的东西:

lowercase_normalizer = normalizer(
    'lowercase_normalizer',
    filter=['lowercase']
)
lowercase_analyzer = analyzer(
    'lowercase_analyzer',
    tokenizer="keyword",
    filter=['lowercase'],
)


@brand.doc_type
class BrandDocument(DocType):

    class Meta:
        model = Brand

    id = IntegerField()
    name = StringField(
        analyzer=lowercase_analyzer,
        fields={
            'raw': Keyword(normalizer=lowercase_normalizer, fielddata=True),
        },
    )

问题仍然存在,但是我在文档中找不到应该如何使用此规范化器。

1 个答案:

答案 0 :(得分:0)

我建议使用小写过滤器创建一个自定义分析器,并在建立索引时将其应用于字段。

因此,您必须在索引设置中更新以下内容:

{
  "index": {
    "analysis": {
      "analyzer": {
        "custom_sort": {
          "tokenizer": "keyword",
          "filter": [
            "lowercase"
          ]
        }
      }
    }
  }
}

使用 custom_sort 分析器在映射中添加字段(需要根据其排序),如下所示:

{
    "properties":{
        "sortField":{
            "type":"text",
            "analyzer":"custom_sort"
        }
    }
}

如果映射中已经存在该字段,则可以使用分析器将子字段添加到现有字段中,如下所示。

假设已经存在类型为 关键字 的字段 name ,请将其更新为:

{
    "properties":{
        "name":{
            "type": "keyword",
            "fields":{
                "sortval":{
                    "type":"text",
                    "analyzer":"custom_sort"
                }
            }
        }
    }
}

完成后,您需要重新索引数据,以便索引小写值。然后,您可以使用该字段将其排序为:

案例1(新字段):

"sort": [
    {
      "sortField": "desc"
    }
  ]

案例2(子字段):

"sort": [
    {
      "name.sortval": "desc"
    }
  ]