2014-05-21 52 views
4

我在評估ElasticSearch是否可以滿足我正在構建的新系統的需求。它看起來很棒,所以我非常希望我能弄清楚一個可行的映射策略。展開父路徑的對象字段的動態映射

在此係統中,管理員可以定義要與文檔動態關聯的字段。因此,給定類型(在彈性搜索的意義上)可以有任何數量的字段,我不知道提前的名稱。並且每個字段可以是任何類型:整型,日期,串等等

示例文檔可能看起來像:

{ 
    "name": "bob", 
    "age": 22, 
    "title": "Vice Intern", 
    "tagline": "Ask not what your company can do for you, but..." 
} 

注意,有2個字符串字段。真棒。但我的問題是,我希望分析「標語」,但我不希望「標題」被分析。

請記住,我不知道這些字段的名稱提前。每種類型可能有多個字段。所以可能有10個不同名稱的字符串字段,其中3個應該被分析,其中7個不應該。

我的另一個要求是,管理員給該字段的名字也應該是他們可以搜索的名字。因此,舉例來說,如果他們想找到所有誰都有話要說副實習生,Lucene的查詢可能是:

+title:"Vice Intern" +tagline:"company" 

所以我的想法是,我可以定義一個動態映射。由於我不知道領域的名字,這似乎是一個很好的方法。關鍵在於提出區分應該分析的字符串字段和不應該的字符串字段的方法!

我想,哎,我只是把所有需要分析到嵌套對象中的字段,如:

{ 
    "name": "bob", 
    "age": 22, 
    "title": "Vice Intern", 
    "textfields": { 
     "tagline": "Ask not what your company can do for you, but...", 
     "somethingelse": "lorem ipsum", 
    } 
}  

然後,在我的動態映射,我不得不映射這些字段的方式不同:

{ 
    "mytype": { 
     "dynamic_templates": { 
      "nested_textfields": { 
       "match": "textfields", 
       "match_mapping_type": "string", 
       "mapping": { 
        "index": "analyzed", 
        "analyzer": "default" 
       } 
      } 
     } 
    } 
} 

我知道這是不對的,其實我需要某種形式的嵌套映射的,但不管,因爲如果我理解正確的話,就算我得到了工作,這將意味着這些字段搜索(通過lucene語法)像這樣:

+title:"Vice Intern" +textfields.tagline:"company" 

而我不想要「textfields」前綴。由於我是提供包裝文本字段的textfields對象的人,因此我知道其中的字段在整個文檔中仍然是唯一命名的。

我想使用模式匹配來代替。因此,不要將它們包裝在「textfields」對象中,我可以將它們作爲前綴,如「textfield_tagline」。但是當這樣做時,動態映射中的{name}標記包含前綴,我沒有看到只是拉出「*」部分的方法。

任何讓我獲得必要行爲的解決方案都是正確答案。即使這涉及嵌套的映射信息到文檔本身(你可以這樣做嗎?我見過類似的東西,我認爲...)。

編輯:

我已經嘗試下面的動態模板。我正在嘗試使用index_name刪除「文本字段」。在索引中。這個動態模板似乎並不匹配,因爲在放置文檔並查看映射後,我看不到指定的分析器。

{ 
     "mytype" : { 
      "dynamic_templates": 
      [ 
      { 
       "textfields": { 
        "path_match": "textfields.*", 
        "match_mapping_type" : "string", 
        "mapping": { 
         "type": "string", 
         "index": "analyzed", 
         "analyzer": "default", 
         "index_name": "{name}", 
         "fields": {     
          "sort": { 
           "type": "string", 
           "index": "not_analyzed", 
           "index_name": "{name}_sort" 
          } 
         } 
        } 
       } 
      } 
      ] 
     } 
    } 
+0

我正在學習嵌套映射和index_name。看起來我應該能夠通過指定它的index_name來爲嵌套屬性(textfields.tagline)提供根級索引名稱。還沒有弄清楚...... – InfinitiesLoop

回答

1

我能夠複製您針對以下索引創建(具有映射),文檔和搜索查詢專門詢問的結果。類型確實有所不同,但它符合示例的目的。

指數設置

PUT http://localhost:9200/sandbox 

{ 
"settings": { 
    "index": { 
    "number_of_shards": 1, 
    "number_of_replicas": 0 
    } 
}, 
"mappings": { 
    "mytype": { 
    "dynamic_templates": [ 
     { 
      "indexedfields": { 
       "path_match": "indexedfields.*", 
       "match_mapping_type" : "string", 
       "mapping": { 
        "type": "string", 
        "index": "analyzed", 
        "analyzer": "default", 
        "index_name": "{name}", 
        "fields": {     
         "sort": { 
          "type": "string", 
          "index": "not_analyzed", 
          "index_name": "{name}_sort" 
         } 
        } 
       } 
      } 
     }, 
     { 
      "textfields": { 
       "path_match": "textfields.*", 
       "match_mapping_type" : "string", 
       "mapping": { 
        "type": "string", 
        "index": "not_analyzed", 
        "index_name": "{name}" 
       } 
      } 
     }, 
     { 
      "strings": { 
       "path_match": "*", 
       "match_mapping_type" : "string", 
       "mapping": { 
        "type": "string", 
        "index": "not_analyzed" 
       } 
      } 

     } 
    ] 
    } 
} 
} 

文件

PUT http://localhost:9200/sandbox/mytype/1 
{ 
    "indexedfields":{ 
     "hello":"Hello world", 
     "message":"The great balls of the world are on fire" 
    }, 
    "textfields":{ 
     "username":"User Name", 
     "projectname":"Project Name" 
    } 
} 

搜索

POST http://localhost:9200/sandbox/mytype/_search 
{ 
    "query": { 
    "query_string": { 
     "query": "message:\"great balls\"" 
    } 
    }, 
    "filter":{ 
     "query":{ 
     "query_string":{ 
      "query":"username:\"User Name\"" 
     } 
     } 
    }, 
    "from":0, 
    "size":10, 
    "sort":[ 

    ] 
} 

搜索返回的FOL低響應:

{ 
    "took":2, 
    "timed_out":false, 
    "_shards":{ 
     "total":1, 
     "successful":1, 
     "failed":0 
    }, 
    "hits":{ 
     "total":1, 
     "max_score":0.19178301, 
     "hits":[ 
     { 
      "_index":"sandbox", 
      "_type":"mytype", 
      "_id":"1", 
      "_score":0.19178301, 
      "_source":{ 
       "indexedfields":{ 
        "hello":"Hello world", 
        "message":"The great balls of the world are on fire" 
       }, 
       "textfields":{ 
        "username":"User Name", 
        "projectname":"Project Name" 
       } 
      } 
     } 
     ] 
    } 
} 
+0

太棒了。看來我已經通過index_name的東西瞭解了很多。我認爲這是行不通的,因爲當我得到生成的_mapping時,沒有「索引」映射,只有非索引映射。但是,正如你告訴我的離線,這只是因爲這是默認,它是省略默認值。真棒。 – InfinitiesLoop