方法1:一個索引一個文檔類型
第一種選擇是每個文檔類型一個索引,作為存儲tweet和user在同一個tweeter索引的替代,你可以存儲tweet在tweets索引里,user在users索引里。索引之間是完全相互隔離的,所以索引里的字段類型不會沖突。
這種方法有兩個好處:
- 數據更緊湊,這樣會更好的利用Lucene的壓縮技術
- 用來做全文檢索評分的字段統計值會更准確,因為在同一個索引里的文檔都代表這同一個實體。
從多type的索引遷移到單type索引的方法:
POST _reindex
{
"source": {
"index": "twitter",
"type": "user"
},
"dest": {
"index": "users"
}
}
POST _reindex
{
"source": {
"index": "twitter",
"type": "tweet"
},
"dest": {
"index": "tweets"
}
}
根據將來要存儲的文檔數量,每個索引大小都可以被合適的度量:你可以把users索引設置更少的主分片,tweets設置更多的主分片。
方法2:自定義type字段
當然,一個集群中主分片的數量是有限制的,所以你可能不想為了幾千個文檔浪費一個分片。這種情況,你可以實現自己的自定義的type字段,它和原來的_type元字段工作原理類似。
讓我們拿上面的tweet/user來舉例,原始的,工作流程像這樣:
PUT twitter
{
"mappings": {
"user": {
"properties": {
"name": { "type": "text" },
"user_name": { "type": "keyword" },
"email": { "type": "keyword" }
}
},
"tweet": {
"properties": {
"content": { "type": "text" },
"user_name": { "type": "keyword" },
"tweeted_at": { "type": "date" }
}
}
}
}
PUT twitter/user/kimchy
{
"name": "Shay Banon",
"user_name": "kimchy",
"email": "shay@kimchy.com"
}
PUT twitter/tweet/1
{
"user_name": "kimchy",
"tweeted_at": "2017-10-24T09:00:00Z",
"content": "Types are going away"
}
GET twitter/tweet/_search
{
"query": {
"match": {
"user_name": "kimchy"
}
}
}
現在,你可以達到同樣的效果,通過添加自定義的type字段:
PUT twitter
{
"mappings": {
"_doc": {
"properties": {
"type": { "type": "keyword" },
"name": { "type": "text" },
"user_name": { "type": "keyword" },
"email": { "type": "keyword" },
"content": { "type": "text" },
"tweeted_at": { "type": "date" }
}
}
}
}
PUT twitter/_doc/user-kimchy
{
"type": "user",
"name": "Shay Banon",
"user_name": "kimchy",
"email": "shay@kimchy.com"
}
PUT twitter/_doc/tweet-1
{
"type": "tweet",
"user_name": "kimchy",
"tweeted_at": "2017-10-24T09:00:00Z",
"content": "Types are going away"
}
GET twitter/_search
{
"query": {
"bool": {
"must": {
"match": {
"user_name": "kimchy"
}
},
"filter": {
"match": {
"type": "tweet"
}
}
}
}
}
無type映射的父子關系
之前,一個父子關系是通過設置一個文檔類型為父,一個或多個映射類型為子,沒有類型(type)的情況下,我們不能使用這種語法。除了父子關系通過新的join字段表示,父子關系的特性和之前一樣起作用。