+3

Case insensitive Sorting trong Elasticsearch

Gần đây, tôi đã gặp một vấn đề thú vị liên quan đến việc sắp xếp trong Elaticsearch. Vấn đề là để đạt được case insensitive for sorting trong ES. Có nhiều cách chúng ta có thể làm điều đó, nhưng hãy đánh giá một vài cách tiếp cận dưới đây:

1. Sử dụng keyword data-type

Một trong những cách tiếp cận phổ biến, khi case sensitivity for sorting không phải là mối quan tâm chính, thì hãy sử dụng type: keyword làm mapping cho field Mapping:

properties": {
    "name": {
        "type": "keyword"
    }
}

Keyword data type:

{
    "name": "Frank Wilson"
}

{
    "name": "andy Wayne"
}

Khi chúng ta áp dụng sắp xếp theo thứ tự giảm dần trên trường name, thì bản ghi đầu tiên trong kết quả là: andy Wayne. Nhưng, vì chúng ta đang sắp xếp theo thứ tự giảm dần, bản ghi đầu tiên phải là Frank Wilson.

Lý do đằng sau hành vi đó là keyword data type, nghĩa là: các giá trị trường của chúng ta không được phân tích và do đó khi ES so sánh ký tự đầu tiên 'a' của andy (giá trị ASCII là 097) và ký tự đầu tiên 'F' của Frank (giá trị ASCII 006) . Ở đây, 'a' có thứ hạng cao hơn vì giá trị ASCII và do đó andy là bản ghi đầu tiên trong kết quả.

Do đó, khi chúng ta chắc chắn rằng tất cả các tài liệu trong chỉ mục sẽ chỉ có giá trị bằng chữ thường hoặc chữ hoa, thì keyword data type sẽ là cách tốt nhất để sử dụng.

Note: Đối với phần còn lại của bài viết, các tài liệu sẽ vẫn giữ nguyên, và chúng ta sẽ chỉ tập trung vào các cách để đạt được mục tiêu.

2. Sử dụng custom analyzer

Tôi đã tạo ra custom analyzer để giải quyết vấn đề insensitive trong trường hợp tôi tạo chỉ mục cho tài liệu với lowercase analyzer. Bên dưới là custom analyzer:

"custom_sort_analyzer": {
    "filter": [
          "lowercase"
    ],
    "tokenizer": "keyword"
}

Và đây là mapping:

"name": {
    "type": "text",
    "analyzer": "custom_sort_analyzer",
    "fielddata": "true"
}

Với mapping trên ta có thể nhận được tài liệu theo đúng thứ tự. Nhưng khoan đã, ở đây chúng ta đã set "fielddata" là true để cho phép field data trong text field, bạn có thể tìm hiểu thêm về fielddata ở đây .

Field data không được ưa thích vì nó có thể tiêu tốn rất nhiều heap space. Do đó, sử dụng field data chắc chắn không phải cách giải quyết tốt nhất.

Sử dụng Normalizer

Normalizer tương tự như analyzer ngoại trừ có thể được áp dụng với keyword data-type field. Chúng ta có thể tìm hiểu thêm normalizer bằng cách tham khảo tài liệu. Phía dưới là custom normalizer:

"normalizer": {
    "custom_sort_normalizer": {
        "type": "custom",
        "char_filter": [],
        "filter": [
            "lowercase",
            "asciifolding"
        ]
    }
}

Mapping:

"name": {
    "type":"keyword",
    "normalizer": "custom_sort_normalizer"
}

Khi chúng ta áp dụng sắp xếp trên trường name, ES sẽ áp dụng custom_sort_normalizer trên tài liệu được lập chỉ mục, lowercase giá trị và áp dụng sắp xếp. Và do đó sẽ trả lại kết quả thích hợp. Đây là giải pháp tối ưu hơn so với analyzer.

4. Kết luận

Trong bài viết này, chúng ta đã đi qua một số cách tiếp cận case sensitivity sorting trong Elaticsearch:

  1. Sử dụng keyword datatype
  2. Sử dụng analyzer
  3. Sử dụng normalizer

Trên tất cả, normalizer là cách tiếp cận tốt nhất vì nó chính xác hơn so với keyword datatype và tối ưu hơn so với analyzer.

Tham khảo:

https://www.technetexperts.com/web/case-insensitive-sorting-in-elasticsearch/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí