【问题标题】:Getting distinct values using NEST ElasticSearch client使用 NEST ElasticSearch 客户端获取不同的值
【发布时间】:2015-04-24 23:27:31
【问题描述】:

我正在使用 NEST 客户端在我的 .NET 应用程序中使用 Elastic Search 构建产品搜索引擎,但我遇到了一件麻烦事。获得一组不同的值。

我正在搜索有数千种产品的产品,但当然我一次只能向用户返回 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");

这甚至是正确的方法吗?还是应该使用完全不同的东西?而且,我怎样才能获得正确、完整的值? (不按空格分割..但我想这就是您要求“术语”列表时得到的结果??)

我正在寻找的是如果你在 MS SQL 中这样做会得到什么

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

【问题讨论】:

    标签: c# .net elasticsearch nest


    【解决方案1】:

    你是正确的,你想要的是一个术语聚合。您遇到的问题是 ES 在返回的结果中拆分了“BrandName”字段。这是 ES 中字段的预期默认行为。

    我建议您将 BrandName 更改为“多字段”,这将允许您搜索所有不同的部分,以及对“未分析”(又名完整的“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
                }
             ]
          }
       }
    }
    

    请注意,未分析的字段将“20th Century fox”和“foo bar”放在一起,而分析的字段会将它们分解。

    【讨论】:

    • 我一周前才开始使用这个。所以我正在开发最新的 1.4.4 版本。
    • 更改 BrandName 是什么意思。更新数据库架构?或者在我的查询中内联更改它?
    • 更改 ES(数据库)索引器。
    • 在创建带有多字段的自定义映射时遇到了一些麻烦,所以我提出了关于该主题的另一个问题。 stackoverflow.com/questions/28681686/…
    • @Bart,我刚刚用一个完整的示例更新了我的答案,应该会让事情更清楚。
    【解决方案2】:

    我遇到了类似的问题。我正在显示搜索结果,并希望显示类别和子类别的计数。

    使用聚合是对的。我还遇到了字符串被标记化的问题(即 20 世纪的狐狸被拆分)——这是因为对字段进行了分析。对我来说,我添加了以下映射(即告诉 ES 不要分析该字段):

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

    正如 jhilden 所建议的,如果您出于多个原因(例如搜索和聚合)使用此字段,则可以将其设置为多字段。所以一方面它可以被分析并用于搜索,另一方面不被分析用于聚合。

    【讨论】:

    • 您的 distinct 和 count 查询是什么样的?听起来很有趣。
    猜你喜欢
    • 2017-12-22
    • 2015-02-19
    • 2012-09-23
    • 2016-08-27
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 2014-06-23
    • 2013-03-31
    相关资源
    最近更新 更多