使用 NEST ElasticSearch 客户端获取不同的值
Getting distinct values using NEST ElasticSearch client
我正在使用 NEST 客户端在我的 .NET 应用程序中使用 Elastic Search 构建一个产品搜索引擎,有一件事我遇到了麻烦。获得一组不同的值。
我正在搜索产品,其中有数千种,但当然我一次只能 return 10 或 20 个给用户。对于这个分页工作正常。但除了这个主要结果之外,我还想向我的用户展示在完整搜索中找到的品牌列表,以展示这些品牌以供过滤。
我了解到我应该为此使用术语聚合。但是,我找不到比这更好的东西了。这仍然没有真正给我我想要的东西,因为它将像“20th Century Fox”这样的值分成 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");
这是正确的方法吗?或者应该使用完全不同的东西?而且,我怎样才能得到正确的、完整的值? (没有被 space 分开 .. 但我想这就是当你要求 'Terms' 的列表时得到的结果??)
我正在寻找的是如果你在 MS 中这样做你会得到什么 SQL
SELECT DISTINCT BrandName FROM [Table To Search] WHERE [Where clause without paging]
您说得对,您想要的是术语聚合。您 运行 遇到的问题是 ES 在它返回的结果中拆分字段 "BrandName"。这是 ES 中字段的预期默认行为。
我建议您将 BrandName 更改为 "Multifield",这将允许您搜索所有不同的部分,以及对 "Not Analyzed"(又名完整“20 世纪福克斯”)术语。
这是来自 ES 的文档。
https://www.elasticsearch.org/guide/en/elasticsearch/reference/0.90/mapping-multi-field-type.html
[更新]
如果您使用的是 ES 版本 1.4 或更新版本,那么多字段的语法现在有点不同。
这是一个完整的工作示例,它说明了 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
}
]
}
}
}
请注意,未分析的字段将“20th century fox”和 "foo bar" 放在一起,而分析的字段将它们分开。
我遇到了类似的问题。我正在显示搜索结果并希望显示类别和子类别的计数。
您使用聚合是正确的。我还遇到了字符串被标记化的问题(即 20th century fox 被拆分)——发生这种情况是因为对字段进行了分析。对我来说,我添加了以下映射(即告诉 ES 不要分析该字段):
"category": {
"type": "nested",
"properties": {
"CategoryNameAndSlug": {
"type": "string",
"index": "not_analyzed"
},
"SubCategoryNameAndSlug": {
"type": "string",
"index": "not_analyzed"
}
}
}
正如 jhilden 所建议的,如果出于多种原因(例如搜索和聚合)使用此字段,则可以将其设置为多字段。因此,一方面它可以被分析并用于搜索,另一方面不被分析用于聚合。
我正在使用 NEST 客户端在我的 .NET 应用程序中使用 Elastic Search 构建一个产品搜索引擎,有一件事我遇到了麻烦。获得一组不同的值。
我正在搜索产品,其中有数千种,但当然我一次只能 return 10 或 20 个给用户。对于这个分页工作正常。但除了这个主要结果之外,我还想向我的用户展示在完整搜索中找到的品牌列表,以展示这些品牌以供过滤。
我了解到我应该为此使用术语聚合。但是,我找不到比这更好的东西了。这仍然没有真正给我我想要的东西,因为它将像“20th Century Fox”这样的值分成 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");
这是正确的方法吗?或者应该使用完全不同的东西?而且,我怎样才能得到正确的、完整的值? (没有被 space 分开 .. 但我想这就是当你要求 'Terms' 的列表时得到的结果??)
我正在寻找的是如果你在 MS 中这样做你会得到什么 SQL
SELECT DISTINCT BrandName FROM [Table To Search] WHERE [Where clause without paging]
您说得对,您想要的是术语聚合。您 运行 遇到的问题是 ES 在它返回的结果中拆分字段 "BrandName"。这是 ES 中字段的预期默认行为。
我建议您将 BrandName 更改为 "Multifield",这将允许您搜索所有不同的部分,以及对 "Not Analyzed"(又名完整“20 世纪福克斯”)术语。
这是来自 ES 的文档。
https://www.elasticsearch.org/guide/en/elasticsearch/reference/0.90/mapping-multi-field-type.html
[更新] 如果您使用的是 ES 版本 1.4 或更新版本,那么多字段的语法现在有点不同。
这是一个完整的工作示例,它说明了 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
}
]
}
}
}
请注意,未分析的字段将“20th century fox”和 "foo bar" 放在一起,而分析的字段将它们分开。
我遇到了类似的问题。我正在显示搜索结果并希望显示类别和子类别的计数。
您使用聚合是正确的。我还遇到了字符串被标记化的问题(即 20th century fox 被拆分)——发生这种情况是因为对字段进行了分析。对我来说,我添加了以下映射(即告诉 ES 不要分析该字段):
"category": {
"type": "nested",
"properties": {
"CategoryNameAndSlug": {
"type": "string",
"index": "not_analyzed"
},
"SubCategoryNameAndSlug": {
"type": "string",
"index": "not_analyzed"
}
}
}
正如 jhilden 所建议的,如果出于多种原因(例如搜索和聚合)使用此字段,则可以将其设置为多字段。因此,一方面它可以被分析并用于搜索,另一方面不被分析用于聚合。