2015-02-23 71 views
7

我正在使用NEST客戶端在我的.NET應用程序中使用Elastic Search構建產品搜索引擎,並且我遇到了一件麻煩事。獲取一組不同的值。使用NEST ElasticSearch客戶端獲取不同的值

我在尋找產品,有成千上萬的產品,但當然我一次只能返回10或20個給用戶。對於這個分頁工作正常。但除了這個主要結果之外,我想向我的用戶展示在完整搜索中找到的品牌列表,以展示這些用於過濾的品牌。

我已閱讀有關我應該使用此術語聚合。但是,我無法得到比這更好的東西。而這仍然不能給我我想要的東西,因爲它將諸如「20世紀福克斯」之類的價值分成3個單獨的價值觀。

var brandResults = client.Search<Product>(s => s 
     .Query(query) 
     .Aggregations(a => a.Terms("my_terms_agg", t => t.Field(p => p.BrandName).Size(250)) 
     ) 
    ); 

    var agg = brandResult.Aggs.Terms("my_terms_agg"); 

這是否正確?或者應該使用完全不同的東西?而且,我如何獲得正確的完整值? (不是按空格拆分..但我想這就是你要求的'條款'列表時得到的結果?)

我在找什麼是你會得到,如果你會這樣做在MS SQL

SELECT DISTINCT BrandName FROM [Table To Search] WHERE [Where clause without paging] 

回答

4

你說得對,你想要的是術語聚合。您遇到的問題是ES正在將它返回的結果中的「BrandName」字段拆分。這是ES中字段的預期默認行爲。

我建議您將BrandName更改爲「Multifield」,這將允許您搜索所有各個部分,以及在「未分析」(又名完整的「20世紀福克斯」 「)術語。

這裏是來自ES的文檔。

https://www.elasticsearch.org/guide/en/elasticsearch/reference/0.90/mapping-multi-field-type.html

[更新] 如果您正在使用ES版本1.4或更新版本的語法,多領域,現在有一點不同。

https://www.elasticsearch.org/guide/en/elasticsearch/reference/current/_multi_fields.html#_multi_fields

這裏是一個完整的工作示例的示出了在ES 1.4.4的點。請注意,映射會指定該字段的「not_analyzed」版本。

PUT hilden1 

PUT hilden1/type1/_mapping 
{ 
    "properties": { 
    "brandName": { 
     "type": "string", 
     "fields": { 
     "raw": { 
      "type": "string", 
      "index": "not_analyzed" 
     } 
     } 
    } 
    } 
} 

POST hilden1/type1 
{ 
    "brandName": "foo" 
} 

POST hilden1/type1 
{ 
    "brandName": "bar" 
} 

POST hilden1/type1 
{ 
    "brandName": "20th Century Fox" 
} 

POST hilden1/type1 
{ 
    "brandName": "20th Century Fox" 
} 

POST hilden1/type1 
{ 
    "brandName": "foo bar" 
} 

GET hilden1/type1/_search 
{ 
    "size": 0, 
    "aggs": { 
    "analyzed_field": { 
     "terms": { 
     "field": "brandName", 
     "size": 10 
     } 
    }, 
    "non_analyzed_field": { 
     "terms": { 
     "field": "brandName.raw", 
     "size": 10 
     } 
    }  
    } 
} 

最後一次查詢的結果:

{ 
    "took": 3, 
    "timed_out": false, 
    "_shards": { 
     "total": 5, 
     "successful": 5, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 5, 
     "max_score": 0, 
     "hits": [] 
    }, 
    "aggregations": { 
     "non_analyzed_field": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "20th Century Fox", 
       "doc_count": 2 
      }, 
      { 
       "key": "bar", 
       "doc_count": 1 
      }, 
      { 
       "key": "foo", 
       "doc_count": 1 
      }, 
      { 
       "key": "foo bar", 
       "doc_count": 1 
      } 
     ] 
     }, 
     "analyzed_field": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "20th", 
       "doc_count": 2 
      }, 
      { 
       "key": "bar", 
       "doc_count": 2 
      }, 
      { 
       "key": "century", 
       "doc_count": 2 
      }, 
      { 
       "key": "foo", 
       "doc_count": 2 
      }, 
      { 
       "key": "fox", 
       "doc_count": 2 
      } 
     ] 
     } 
    } 
} 

注意,不是分析的領域保持「20世紀福克斯」和「富巴」在一起,其中作爲分析的領域打破了起來。

+0

我剛剛從一週前開始。所以我正在研究最新的1.4.4版本。 – Bart 2015-02-23 15:52:43

+0

你是什麼意思改變品牌名稱。更新數據庫模式?或者在我的查詢中改變它內聯? – Bart 2015-02-23 15:59:26

+0

更改ES(數據庫)索引器。 – jhilden 2015-02-23 16:40:36

1

我有類似的問題。我正在顯示搜索結果並希望顯示類別和子類別的計數。

你是對的使用聚合。我也遇到了字符串被標記的問題(即20世紀的狐狸被分裂) - 這是因爲字段被分析。對於我來說,我添加了以下映射(即告訴ES不是分析這一領域):

"category": { 
      "type": "nested", 
      "properties": { 
      "CategoryNameAndSlug": { 
       "type": "string", 
       "index": "not_analyzed" 
      }, 
      "SubCategoryNameAndSlug": { 
       "type": "string", 
       "index": "not_analyzed" 
      } 
      } 
     } 

由於jhilden建議,如果你使用這個領域超過一個原因(例如搜索和聚合),您可以將其設置爲多字段。所以一方面它可以被分析和用於搜索,另一方面可以不被分析用於聚合。

+0

已經很清楚了。謝謝(你的)信息! – Bart 2015-02-23 16:52:26

+0

你的獨特和計數查詢是什麼樣的?聽起來很有趣。 – Bart 2015-02-23 17:06:52