2012-08-24 21 views
16

giả sử rằng trong chỉ mục elasticsearch của tôi, tôi có một trường được gọi là "dấu chấm" sẽ chứa một chuỗi các từ được phân cách bằng dấu chấm câu (ví dụ: "first.second.third").Cách đối sánh trên tiền tố trong Elasticsearch

Tôi cần tìm kiếm ví dụ: "first.second" và sau đó nhận tất cả các mục có trường "dấu chấm" chứa chuỗi là chính xác "first.second" hoặc bắt đầu bằng "first.second".

Tôi gặp sự cố khi hiểu cách truy vấn văn bản hoạt động, ít nhất tôi không thể tạo truy vấn thực hiện công việc.

Trả lời

20

Elasticsearch có Path Hierarchy Tokenizer được tạo chính xác cho trường hợp sử dụng đó. Dưới đây là một ví dụ về cách thiết lập nó cho chỉ số của bạn:

# Create a new index with custom path_hierarchy analyzer 
# See http://www.elasticsearch.org/guide/reference/index-modules/analysis/pathhierarchy-tokenizer.html 
curl -XPUT "localhost:9200/prefix-test" -d '{ 
    "settings": { 
     "analysis": { 
      "analyzer": { 
       "prefix-test-analyzer": { 
        "type": "custom", 
        "tokenizer": "prefix-test-tokenizer" 
       } 
      }, 
      "tokenizer": { 
       "prefix-test-tokenizer": { 
        "type": "path_hierarchy", 
        "delimiter": "." 
       } 
      } 
     } 
    }, 
    "mappings": { 
     "doc": { 
      "properties": { 
       "dots": { 
        "type": "string", 
        "analyzer": "prefix-test-analyzer", 
        //"index_analyzer": "prefix-test-analyzer", //deprecated 
        "search_analyzer": "keyword" 
       } 
      } 
     } 
    } 
}' 
echo 
# Put some test data 
curl -XPUT "localhost:9200/prefix-test/doc/1" -d '{"dots": "first.second.third"}' 
curl -XPUT "localhost:9200/prefix-test/doc/2" -d '{"dots": "first.second.foo-bar"}' 
curl -XPUT "localhost:9200/prefix-test/doc/3" -d '{"dots": "first.baz.something"}' 
curl -XPOST "localhost:9200/prefix-test/_refresh" 
echo 
# Test searches. 
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true" -d '{ 
    "query": { 
     "term": { 
      "dots": "first" 
     } 
    } 
}' 
echo 
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true" -d '{ 
    "query": { 
     "term": { 
      "dots": "first.second" 
     } 
    } 
}' 
echo 
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true" -d '{ 
    "query": { 
     "term": { 
      "dots": "first.second.foo-bar" 
     } 
    } 
}' 
echo 
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true&q=dots:first.second" 
echo 
+0

Xin lỗi, không thấy bài đăng của bạn cho đến bây giờ !! Cảm ơn rất nhiều :) Sẽ nhìn vào nó ngay sau khi tôi nhận được thời gian! – Stine

+0

Làm cách nào để thực hiện các cài đặt và ánh xạ trong mã Java của tôi? – Stine

+1

'client.admin(). Index(). PrepareCreate (" test "). AddMapping (" type1 ", mapping) .setSettings (cài đặt) .execute(). ActionGet();' – imotov

2

Có một cái nhìn tại prefix queries.

$ curl -XGET 'http://localhost:9200/index/type/_search' -d '{ 
    "query" : { 
     "prefix" : { "dots" : "first.second" } 
    } 
}' 
+1

Không hoạt động khi chuỗi chứa dấu câu:/ – Stine

+1

[This] (https://gist.github.com/3457388) hoạt động trên chỉ mục mới.Bạn có bản đồ đặc biệt về chỉ mục của mình không? Có lẽ bạn nên thử một chỉ số mới, sạch sẽ. – A21z

+0

Có sự khác biệt hiệu quả nào giữa việc sử dụng tìm kiếm tiền tố hoặc trình mã thông báo phân cấp đường dẫn không? –

1

Ngoài ra còn có một cách dễ dàng hơn nhiều, như đã chỉ ra trong elasticsearch documentation:

chỉ cần sử dụng:

{ 
    "text_phrase_prefix" : { 
     "fieldname" : "yourprefix" 
    } 
} 

hoặc kể từ 0.19.9:

{ 
    "match_phrase_prefix" : { 
     "fieldname" : "yourprefix" 
    } 
} 

thay vì:

{ 
    "prefix" : { 
     "fieldname" : "yourprefix" 
} 
1

Tôi đang tìm một giải pháp tương tự - nhưng chỉ khớp với tiền tố. Tôi thấy @ imtov của answer để làm cho tôi gần như ở đó, nhưng đối với một sự thay đổi - chuyển đổi các máy phân tích xung quanh:

"mappings": { 
    "doc": { 
     "properties": { 
      "dots": { 
       "type": "string", 
       "analyzer": "keyword", 
       "search_analyzer": "prefix-test-analyzer" 
      } 
     } 
    } 
} 

thay vì

"mappings": { 
    "doc": { 
     "properties": { 
      "dots": { 
       "type": "string", 
       "index_analyzer": "prefix-test-analyzer", 
       "search_analyzer": "keyword" 
      } 
     } 
    } 
} 

Bằng cách này nói thêm:

'{"dots": "first.second"}' 
'{"dots": "first.third"}' 

Sẽ thêm chỉ những mã thông báo đầy đủ này, không lưu trữ first, second, third mã thông báo.

Tuy nhiên, tìm kiếm hoặc

first.second.anyotherstring 
first.second 

sẽ trở lại một cách chính xác chỉ mục đầu tiên:

'{"dots": "first.second"}' 

Không chính xác những gì bạn yêu cầu nhưng có liên quan bằng cách nào đó, vì vậy tôi nghĩ có thể giúp ai đó.

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