2015-07-01 26 views
6

API REST của chúng tôi cho phép người dùng thêm JSON schemaless tùy chỉnh vào một số tài nguyên REST của chúng tôi và chúng tôi cần nó để có thể tìm kiếm trong Elasticsearch. Dữ liệu tùy chỉnh này và cấu trúc của nó có thể hoàn toàn khác nhau trên các tài nguyên cùng loại.Hỗ trợ Schemaless cho truy vấn tìm kiếm đàn hồi

Xem xét tài liệu ví dụ này:

{ 
    "givenName": "Joe", 
    "username": "joe", 
    "email": "[email protected]", 
    "customData": { 
    "favoriteColor": "red", 
    "someObject": { 
     "someKey": "someValue" 
    } 
    } 
} 

Tất cả các lĩnh vực trừ customData tuân theo một sơ đồ. customData luôn là đối tượng JSON, nhưng tất cả các trường và giá trị bên trong đối tượng đó có thể khác nhau đáng kể từ tài nguyên đến tài nguyên. Không có đảm bảo rằng bất kỳ tên trường hoặc giá trị nào (hoặc thậm chí cả loại giá trị) trong customData giống nhau trên bất kỳ hai tài nguyên nào khi người dùng có thể chỉnh sửa các trường này theo ý muốn.

Cách tốt nhất để hỗ trợ tìm kiếm điều này là gì?

Chúng tôi nghĩ rằng một giải pháp là không tạo ra bất kỳ ánh xạ nào cho customData khi chỉ mục được tạo, nhưng sau đó nó trở thành không thể truy vấn (trái với những gì ES docs say). Đây sẽ là giải pháp lý tưởng nếu các truy vấn trên các thuộc tính không được ánh xạ hoạt động và không có vấn đề về hiệu suất với phương pháp này. Tuy nhiên, sau khi chạy nhiều thử nghiệm cho vấn đề đó, chúng tôi đã không thể làm điều đó để hoạt động.

Đây có phải là thứ cần bất kỳ cấu hình đặc biệt nào không? Hoặc là các tài liệu không chính xác? Một số làm rõ về lý do tại sao nó không hoạt động sẽ được đánh giá cao.

Do đây là không hiện đang làm việc cho chúng tôi, chúng tôi đã nghĩ ra một vài giải pháp thay thế:

  1. Reindexing: đây sẽ là tốn kém như chúng ta sẽ cần phải reindex mỗi chỉ số có chứa tài liệu đó và làm vì vậy mỗi khi người dùng cập nhật thuộc tính với một loại giá trị khác. Thực sự xấu cho hiệu suất, vì vậy đây có thể không phải là một lựa chọn thực sự.

  2. Sử dụng multi-match query: chúng tôi sẽ thực hiện việc này bằng cách thêm một chuỗi ngẫu nhiên vào tên trường tùy chỉnh mỗi khi có thay đổi trong đối tượng customData. Ví dụ, đây là những gì các tài liệu được lập chỉ mục sẽ trông như thế:

    { 
        "givenName": "Joe", 
        "username": "joe", 
        "email": "[email protected]", 
        "customData_03ae8b95-2496-4c8d-9330-6d2058b1bbb9": { 
        "favoriteColor": "red", 
        "someObject": { 
         "someKey": "someValue" 
        } 
        } 
    } 
    

    Điều này có nghĩa ES sẽ tạo ra một bản đồ mới cho mỗi trường 'ngẫu nhiên', và chúng tôi sẽ sử dụng cụm từ truy vấn đa kết hợp sử dụng một "bắt đầu với "thẻ hoang dã cho tên trường khi thực hiện các truy vấn. Ví dụ:

    curl -XPOST 'eshost:9200/test/_search?pretty' -d ' 
    { 
        "query": { 
        "multi_match": { 
         "query" : "red", 
         "type" : "phrase", 
         "fields" : ["customData_*.favoriteColor"] 
        } 
        } 
    }' 
    

    Đây có thể là giải pháp khả thi, nhưng chúng tôi lo ngại rằng có quá nhiều ánh xạ như thế này có thể ảnh hưởng đến hiệu suất. Có bất kỳ hậu quả hiệu suất nào cho việc có quá nhiều ánh xạ trên một chỉ mục không? Có thể tái diễn định kỳ có thể làm giảm bớt quá nhiều ánh xạ?

    Điều này cũng chỉ cảm thấy giống như một hack và một cái gì đó cần được xử lý bởi ES nguyên bản. Tui bỏ lỡ điều gì vậy?

Bất kỳ đề xuất nào về điều này sẽ được đánh giá cao.

Cảm ơn!

Trả lời

0

Các trường có cùng ánh xạ sẽ được lưu trữ dưới dạng cùng trường đơn thuần trong chỉ mục Lucene (Elasticsearch shard).Trường Lucene khác nhau sẽ có chỉ mục đảo ngược riêng biệt (mục dict và mục nhập chỉ mục) và các giá trị doc riêng biệt. Lucene được tối ưu hóa cao để lưu trữ tài liệu của cùng một lĩnh vực một cách nén. Việc sử dụng ánh xạ với trường khác nhau cho tài liệu khác nhau sẽ ngăn không cho quá trình tối ưu hóa.

Bạn nên sử dụng Elasticsearch Nested Document để tìm kiếm hiệu quả. Công nghệ cơ bản là Lucene BlockJoin, chỉ định các tài liệu cha/con là một khối tài liệu.

+0

bạn đang nói rằng Tài liệu lồng nhau có thể xử lý tính chất không xác định được mô tả của đối tượng 'customData' không? –

2

Bạn chính xác rằng Elasticsearch không thực sự là sơ đồ. Nếu không có ánh xạ được chỉ định, Elasticsearch sẽ đưa vào các kiểu dữ liệu kiểu trường dựa trên giá trị đầu tiên mà nó nhìn thấy cho trường đó. Do đó, đối tượng customData không xác định của bạn có thể khiến bạn gặp rắc rối nếu bạn nhìn thấy lần đầu tiên "favoriteColor": 10 theo sau là "favoriteColor": "red". Đối với yêu cầu của bạn, bạn nên xem SIREn Solutions Elasticsearch plugin cung cấp giải pháp schemaless cùng với ngôn ngữ truy vấn nâng cao (sử dụng Twig) và định dạng chỉ mục Lucene tùy chỉnh để tăng tốc các hoạt động lập chỉ mục và tìm kiếm cho dữ liệu không xác định .

+0

Cảm ơn Peter bình luận - chúng tôi sẽ thử nó ra và giải thưởng câu trả lời nếu nó hoạt động như mong đợi. –

Các vấn đề liên quan