12/08/2018, 11:44

Loại bỏ trùng lặp dữ liệu trong ElasticSearch

Loại bỏ trùng lặp dữ liệu luôn được xem là một việc cần phải làm, và khi thực hiện công việc đó, tức là loại bỏ những dữ liệu trùng lặp thì chúng ta sẽ đạt được nhiều lợi ích nhất định. Trong ElasticSearch cũng vậy, bạn sẽ đạt được một số lợi ích như sau: Tiết kiệm được dung lượng ổ cứng Tăng ...

Loại bỏ trùng lặp dữ liệu luôn được xem là một việc cần phải làm, và khi thực hiện công việc đó, tức là loại bỏ những dữ liệu trùng lặp thì chúng ta sẽ đạt được nhiều lợi ích nhất định. Trong ElasticSearch cũng vậy, bạn sẽ đạt được một số lợi ích như sau:

  • Tiết kiệm được dung lượng ổ cứng
  • Tăng tính chính xác khi tìm kiếm
  • Nâng cao hiểu quả quản lý tài nguyên của phần cứng
  • Giảm thời gian tìm kiếm

Bài viết này sẽ cung cấp cho bạn những kỹ thuật thích hợp để xác định và quản lý các bản ghi trùng lặp trong dữ liệu.

image

Dữ liệu mẫu

Chúng ta có 4 documents, một trong số đó là trùng lặp với documents khác. Chúng ta sẽ index những document này thông qua employeeid và với type info

Document 1

curl -XPOST 'http://localhost:9200/employeeid/info/1' -d '{
 "name": "John",
 "organisation": "Apple",
 "employeeID": "23141A"
 }'

Document 2

curl -XPOST 'http://localhost:9200/employeeid/info/2' -d '{
 "name": "Sam",
 "organisation": "Tesla",
 "employeeID": "TE9829"
 }'

Document 3

curl -XPOST 'http://localhost:9200/employeeid/info/3' -d '{
 "name":"Sarah",
 "organisation":"Microsoft",
 "employeeID" :"M54667"
 }'

Document 4

curl -XPOST 'http://localhost:9200/employeeid/info/4' -d '{
 "name": "John",
 "organisation": "Apple",
 "employeeID": "23141A"
 }'

Tất nhiên bạn sẽ thấy được document 4 là trùng lặp với document 1

Trùng lặp dữ liệu trong quá trình Indexing

Trước khi chia sẻ như thế nào để kiểm tra trùng lặp trong ElasticSearch, chúng ta cùng xem xét một vài kịch bản indexing để thấy được sự khác nhau giữa các type.

Kịch bản thứ nhất là chúng ta có quyền truy cập vào document để indexing. Trường hợp này khá là dễ dàng để kiểm tra dữ liệu có uniq hay không. Điều này có nghĩa là mỗi giá trị riêng biệt chỉ trỏ đến một document. Thông thường với trường hợp như vậy thì chúng ta sử dụng id cho mỗi ElasticSearch index. Chính vì thế nên những documents trùng lặp đều sẽ có cùng id. Do đó, ElasticSearch sẽ đảm bảo những document trùng lặp đó sẽ không trở thành một phần của index.

Upsert

Trong một trường hợp khác, có một hoặc nhiều document có cùng định danh nhưng khác nội dung. Vấn đề này xảy ra khi mà người dùng thay đổi document và muốn reindex document đó sử dụng cùng id. Tất nhiên là người sử dụng phải ép buộc ElasticSearch để reindex, tuy nhiên ElasticSearch không cho phép điều đó, bởi vì document id luôn phải là uniq.

Giải pháp cho vấn đề này là sử dụng upsert API . Upsert có nhiệm vụ kiểm tra trạng thái của những document riêng biệt, nếu đã tồn tại, upsert sẽ cập nhật document cùng với nội dung của upsert. Ngược lại, document không tồn tại, upsert sẽ tạo ra một document có cùng nội dung. Dù sao đi nữa thì người dùng sẽ lấy dữ liệu từ chính document đó.

Với trường hợp này, chúng ta không thể truy cập dữ liệu trước để tạo indexing. Đây là một trong những trường hợp mà chúng ta cần tìm kiếm index và kiểm tra trùng lặp. Chúng ta sẽ demo ở phía dưới.

Cơ bản về kiểm tra trùng lặp dữ liệu

Trong ví dụ documents, chúng ta thấy 2 trường name, organisation, employeeid và nếu giả định trường name là uniq, chúng ta sẽ sử dụng name để kiểm tra trùng lặp. Nếu có nhiều hơn 1 document có cùng name thì đó là document trùng lặp.

Dựa vào điểu đó thì chúng ta thực hiện terms aggregation để lấy được số lượng document có cùng name. Tuy nhiên, nó chỉ trả về cho chúng ta số lượng tương ứng với giá trị trong trường đó. Vậy nên phương pháp tiếp cận này không giúp ích được trong việc kiểm tra trùng lặp bởi vì chúng ta muốn kiểm tra cho một hoặc nhiều giá trị. Để làm được điều đó, chúng ta cần áp dụng top_hit aggregation - một subaggregator, trong đó các document phù hợp sẽ được tổng hợp vào mỗi bucket.

Và với ví dụ trên chúng ta có query sau:

curl -XGET 'http://localhost:9200/employeeid/info/_search?pretty=true' -d '{
  "size": 0,
  "aggs": {
    "duplicateCount": {
      "terms": {
        "field": "name",
        "min_doc_count": 2
      },
      "aggs": {
        "duplicateDocuments": {
          "top_hits": {}
        }
      }
    }
  }
}'

Parameter min_doc_count được set giá trị là 2, có nghĩa là chỉ những buckets có doc_count nhiều hơn 2 xuất hiện trong tập hợp sẽ được trả về. Và kết quả chúng ta có là:

{
  "took" : 17,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 4,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "duplicateCount" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [ {
        "key" : "john",
        "doc_count" : 2,
        "duplicateDocuments" : {
          "hits" : {
            "total" : 2,
            "max_score" : 1.0,
            "hits" : [ {
              "_index" : "employeeid",
              "_type" : "info",
              "_id" : "4",
              "_score" : 1.0,
              "_source":{
                  "name": "John",
                  "organisation": "Apple",
                  "employeeID": "23141A"
                }
              }, {
              "_index" : "employeeid",
              "_type" : "info",
              "_id" : "1",
              "_score" : 1.0,
              "_source":{
                "name": "John",
                "organisation": "Apple",
                "employeeID": "23141A"
              }
            } ]
          }
        }
      } ]
    }
  }
}

Điều quan trọng cần chú ý là chúng ta cần phải set min_doc_count là 2. Nếu không, kết quả khác xuất hiện trong buckets và chúng ta sẽ không có được kết quả mong muốn.

Trùng lặp dữ liệu trên nhiều giá trị trong nhiều fields

Những gì chúng ta vừa làm ở phía trên chỉ là những kiến thức cơ bản để xác định duplicate document theo giá trị trên một field. Trong thực tế, kiểm tra trùng lặp thường yêu cầu trên nhiều giá trị trong nhiều field. Chúng ta không thể chắc chắn được những employee document chỉ lặp lại giá trị Bill trong field name. Trên thực tế, thực sự cần thiết để kiểm tra thông qua nhiều fields. Xét cho ví dụ của chúng ta thì cần kiểm tra cho tất cả các field.

Chúng ta có thể mở rộng hướng tiếp cận cho những phần trước và thực hiện terms aggreation cùng với top-hits aggreation trên nhiều field. Để làm được việc đó chúng ta sử dụng scipt để thêm các field, và đừng quên min_doc_count và top_hits

curl -XGET 'http://localhost:9200/employeeid/info/_search?pretty=true' -d '{
  "size": 0,
  "aggs": {
    "duplicateCount": {
      "terms": {
        "script": "doc['name'].values + doc['employeeID'].values+doc['organisation'].values",
        "min_doc_count": 2
      },
      "aggs": {
        "duplicateDocuments": {
          "top_hits": {}
        }
      }
    }
  }
}'

Và kết quả chúng ta nhận được là

{
  "took": 9,
  "timed_out": false,
  "_shards": {
    "total": 4,
    "successful": 4,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0,
    "hits": [

    ]
  },
  "aggregations": {
    "duplicateCount": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "23141a",
          "doc_count": 2,
          "duplicateDocuments": {
            "hits": {
              "total": 2,
              "max_score": 1,
              "hits": [
                {
                  "_index": "employeeid",
                  "_type": "info",
                  "_id": "4'",
                  "_score": 1,
                  "_source": {
                    "name": "John",
                    "organisation": "Apple",
                    "employeeID": "23141A"
                  }
                },
                {
                  "_index": "employeeid",
                  "_type": "info",
                  "_id": "1'",
                  "_score": 1,
                  "_source": {
                    "name": "John",
                    "organisation": "Apple",
                    "employeeID": "23141A"
                  }
                }
              ]
            }
          }
        },
        {
          "key": "apple",
          "doc_count": 2,
          "duplicateDocuments": {
            "hits": {
              "total": 2,
              "max_score": 1,
              "hits": [
                {
                  "_index": "employeeid",
                  "_type": "info",
                  "_id": "4'",
                  "_score": 1,
                  "_source": {
                    "name": "John",
                    "organisation": "Apple",
                    "employeeID": "23141A"
                  }
                },
                {
                  "_index": "employeeid",
                  "_type": "info",
                  "_id": "1'",
                  "_score": 1,
                  "_source": {
                    "name": "John",
                    "organisation": "Apple",
                    "employeeID": "23141A"
                  }
                }
              ]
            }
          }
        },
        {
          "key": "john",
          "doc_count": 2,
          "duplicateDocuments": {
            "hits": {
              "total": 2,
              "max_score": 1,
              "hits": [
                {
                  "_index": "employeeid",
                  "_type": "info",
                  "_id": "4'",
                  "_score": 1,
                  "_source": {
                    "name": "John",
                    "organisation": "Apple",
                    "employeeID": "23141A"
                  }
                },
                {
                  "_index": "employeeid",
                  "_type": "info",
                  "_id": "1'",
                  "_score": 1,
                  "_source": {
                    "name": "John",
                    "organisation": "Apple",
                    "employeeID": "23141A"
                  }
                }
              ]
            }
          }
        }
      ]
    }
  }
}

Như vậy chúng ta đã hoàn thành việc tìm hiểu và đưa ra các giải pháp cho vấn đề loại bỏ trùng lặp dữ liệu trong ElasticSearch.

Nguồn tham khảo qbox.io

0