2013-11-01 14 views
5

Chúng tôi đang gặp một số khó khăn trong việc tìm ra cách quản lý tốt nhất các trường được mã hóa và không được kiểm soát của chúng tôi cho cả tìm kiếm và sắp xếp. mục tiêu của chúng tôi là khá đơn giản:Áp dụng mẫu động cho nhiều loại - để quản lý mã thông báo để phân loại

  1. Hỗ trợ từ phần tìm kiếm
  2. Hỗ trợ phân loại trên tất cả mọi lĩnh vực
  3. lập bản đồ của chúng tôi phải năng động, khách hàng thêm lĩnh vực mới khi chạy.

Chúng tôi có thể thực hiện việc này bằng mẫu động. Chúng tôi lưu trữ các chuỗi bằng cách sử dụng trình mã thông báo mặc định, trình mã thông báo tùy chỉnh, ngram và trình kiểm duyệt không được kiểm duyệt. Các bản đồ:

curl -XPUT 'http://testServer:9200/test/' -d '{ 
     "settings": { 
      "analysis": { 
       "analyzer": { 
        "my_ngram_analyzer": { 
         "tokenizer": "my_ngram_tokenizer", 
         "filter": [ 
          "lowercase" 
         ], 
         "type" : "custom" 
        }, 
        "default_search": { 
         "tokenizer" : "keyword", 
         "filter" : [ 
          "lowercase" 
         ] 
        } 
       }, 
       "tokenizer": { 
        "my_ngram_tokenizer": { 
         "type": "nGram", 
         "min_gram": "3", 
         "max_gram": "100", 
         "token_chars": [] 
        } 
       } 
      } 
     }, 
     "mappings": { 
      "TestObject": { 
       "dynamic_templates": [ 
        { 
         "metadata_template": { 
          "match_mapping_type": "string", 
          "path_match": "*", 
          "mapping": { 
           "type": "multi_field", 
           "fields": { 
            "ngram": { 
             "type": "{dynamic_type}", 
             "index": "analyzed", 
             "index_analyzer": "my_ngram_analyzer", 
             "search_analyzer" : "default_search" 
            }, 
            "{name}": { 
             "type": "{dynamic_type}", 
             "index": "analyzed", 
             "index_analyzer" : "standard", 
             "search_analyzer" : "default_search" 
            }, 
            "sortable": { 
             "type": "{dynamic_type}", 
             "index": "analyzed", 
             "analyzer" : "default_search" 
            } 
           } 
          } 
         } 
        } 
       ] 
      } 
     } 
    }' 

Chúng tôi thực sự chỉ giữ lại những lĩnh vực được phân tích xung quanh để phân loại và kết hợp chính xác (. Chúng tôi thậm chí gọi nó, 'sắp xếp được') Cấu hình này làm cho nó dễ dàng cho chúng tôi để có được tìm kiếm từ một phần, nếu truy vấn là truy vấn "chứa" - chúng tôi nối ".ngram" vào mục tiêu truy vấn. Vấn đề mà chúng tôi đang gặp phải là quyết định thời điểm sử dụng hậu tố ".sortable". Nếu chúng tôi nhận được yêu cầu sắp xếp ngày dateUpdated, ví dụ: chúng tôi không muốn sử dụng .sortable, vì trường đó là ngày. Nếu Yêu cầu sắp xếp theo 'tên', chúng tôi muốn sử dụng nó, vì trường đó là một chuỗi và không sử dụng nó nếu chúng ta đang cố gắng sắp xếp theo 'giá'.

Logic để kiểm tra loại trường trước khi sắp xếp có vẻ ít kludgy (chúng tôi kiểm tra trong mô hình của chúng tôi, thay vì kiểm tra loại trong elasticsearch) .Nó sẽ rất tuyệt khi LUÔN LUÔN có trường '.sortable' xung quanh, nhưng chúng tôi không thể chạy các loại không phải chuỗi thông qua mẫu động dưới đây và các số không thể chạy qua bộ lọc ngram.

Có ai có đề xuất về cách chúng tôi luôn có thể có trường "có thể phân loại" để sắp xếp, không bao giờ được mã hóa không phân biệt loại đó? Hoặc có thể bạn có một giải pháp tốt hơn cho loại vấn đề mà chúng ta không thấy? Cảm ơn trước!

Trả lời

4

Điều này thực sự luộc xuống là chúng tôi luôn muốn có trường "có thể sắp xếp" (mà chúng tôi đổi tên thành "không được phân tích" vì nó có sử dụng khác) trên mọi trường được ánh xạ. Bí quyết thực sự để làm điều này, mà không cần thêm một mẫu động mới cho mọi loại, là tạo một mẫu động có thể áp dụng cho mọi loại khác ngoài một chuỗi. Để làm điều đó, bạn cần phải thiết lập match_pattern để regex:

  { 
       "other_types": { 
        "match_mapping_type": "date|boolean|double|long|integer", 
        "match_pattern": "regex", 
        "path_match": ".*", 
        "mapping": { 
         "type": "multi_field", 
         "fields": { 
          "{name}": { 
           "type": "{dynamic_type}", 
           "index": "not_analyzed" 
          }, 
          "unanalyzed": { 
           "type": "{dynamic_type}", 
           "index": "not_analyzed" 
          } 
         } 
        } 
       } 
      } 

Lưu ý rằng bạn cần phải thực hiện một sự thay đổi nhỏ để "path_match" như nổi bạn phải sử dụng một biểu hiện bất thường (như trái ngược với '*' Đó là một biểu thức 'đơn giản' của ES.)

Hạn chế duy nhất cho điều này là chúng tôi đang tăng kích thước chỉ mục của mình - chúng tôi lưu trữ tất cả các loại này hai lần. Vì mục đích của chúng tôi, các chỉ mục của chúng tôi (chúng tôi có nhiều) có nhiều chỗ để phát triển và đáng để tránh phải thực hiện loại tìm kiếm trên mọi trường trước khi thực hiện truy vấn chính xác hoặc sắp xếp (chỉ cần sử dụng $ {fieldName} .unanalyzed).

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