elasticsearch,Php,elasticsearch" /> elasticsearch,Php,elasticsearch" />

Php 多词值问题的聚合

Php 多词值问题的聚合,php,elasticsearch,Php,elasticsearch,我正在基于Elasticsearch构建分层导航。我的产品有“品牌”领域。例如,我有两个品牌-汤米牛仔裤和汤米希尔菲格。当我尝试使用以下查询聚合结果时 $params = [ 'index' => 'my_index', 'type' => 'my_type', 'body' => [ 'query' => [ 'term' => [ 'brand' => 'to

我正在基于Elasticsearch构建分层导航。我的产品有“品牌”领域。例如,我有两个品牌-汤米牛仔裤和汤米希尔菲格。当我尝试使用以下查询聚合结果时

$params = [
    'index' => 'my_index',
    'type' => 'my_type',
    'body' => [
        'query' => [
            'term'  => [
                'brand' => 'tommy'
            ]
        ],
        'aggs' => [
            'brand' => [
                'terms' => [
                    'field' => 'brand',
                ]
            ]
        ]
    ]
];
我希望括号里有两个结果——汤米·希尔菲格和汤米·牛仔裤,结果都很重要,但我的情况是这样的

[aggregations] => Array
    (
        [brand] => Array
            (
                [doc_count_error_upper_bound] => 0
                [sum_other_doc_count] => 0
                [buckets] => Array
                    (
                        [0] => Array
                            (
                                [key] => tommy
                                [doc_count] => 6
                            )

                        [1] => Array
                            (
                                [key] => hilfiger
                                [doc_count] => 4
                            )

                        [2] => Array
                            (
                                [key] => jeans
                                [doc_count] => 2
                            )

                    )

            )

    )

如何解决这个问题?

这可以通过将
品牌
字段设置为
文本
类型,并向其添加一个子字段,如
关键字
,类型为
关键字
。然后,您需要使用
term
字段
brand
上的查询来过滤结果,并在字段
brand.keyword上进行聚合

因此,映射将是:

{
  "mappings": {
    "_doc": {
      "properties": {
        "brand": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        }
      }
    }
  }
}
更新注释:旧版本es(2.x)的映射:

以下是查询:

{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "brand": "tommy"
          }
        }
      ]
    }
  },
  "aggs": {
    "brand": {
      "terms": {
        "field": "brand.keyword"
      }
    }
  }
}

最后,我终于明白了我的问题。这是一个有效的例子(基于Nishant Saini的回答)


“类型”:“关键字”是一种新格式,旧版本仅支持“字符串”类型。无论如何,在我的情况下,你的例子不起作用。我正在解决这个问题,并在下面发布一个工作示例。es(2.x)的更新答案是的,在我发布解决方案之后,请阅读“字段”。非常感谢。在这种情况下,开销是您需要单独发送
原始品牌
的值,这可以通过使用子字段来避免。请参阅我的最新答案。
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "brand": "tommy"
          }
        }
      ]
    }
  },
  "aggs": {
    "brand": {
      "terms": {
        "field": "brand.keyword"
      }
    }
  }
}
use Elasticsearch\ClientBuilder;

require 'vendor/autoload.php';

echo '<pre>';

$client = ClientBuilder::create()->build();

$params = [
    'index' => 'my_index',
    'body' => [
        'mappings' => [
            'my_type' => [
                'properties' => [
                    'brand' => [
                        'type'  => 'string',
                        'fields'    => [
                            'keyword'   => [
                                'type'  => 'string',
                                'index' => 'not_analyzed'
                            ]
                        ]
                    ],
                    'color' => [
                        'type'  => 'string',
                        'fields'    => [
                            'keyword'   => [
                                'type'  => 'string',
                                'index' => 'not_analyzed'
                            ]
                        ]
                    ],
                    'category' => [
                        'type'  => 'string',
                        'fields'    => [
                            'keyword'   => [
                                'type'  => 'string',
                                'index' => 'not_analyzed'
                            ]
                        ]
                    ],
                    'id' => [
                        'type'  => 'integer',
                    ]   
                ]
            ]
        ]
    ]
];

$client->indices()->create($params);

$items = [
    [
        'id'        => 1,
        'category'  => 'Jackets',
        'brand'     => 'Tommy Hilfiger',
        'color'     => 'Red'
    ],
    [
        'id'        => 2,
        'category'  => 'Jeans',
        'brand'     => 'Tommy Jeans',
        'color'     => 'Navy'
    ],
    [
        'id'        => 3,
        'category'  => 'Shirts',
        'brand'     => 'Tommy Hilfiger',
        'color'     => 'Maroon'
    ],
    [
        'id'        => 4,
        'category'  => 'Trousers',
        'brand'     => 'Tommy Jeans',
        'color'     => 'Grey'
    ],
    [
        'id'        => 5,
        'category'  => 'Shirts',
        'brand'     => 'Tommy Hilfiger',
        'color'     => 'Grey'
    ],
    [
        'id'        => 6,
        'category'  => 'Sneakers',
        'brand'     => 'Tommy Jeans',
        'color'     => 'Grey'
    ],
    [
        'id'        => 7,
        'category'  => 'Sneakers',
        'brand'     => 'Tommy Jeans',
        'color'     => 'Grey'
    ]
];

foreach ($items as $item) {
    $params = [
        'index' => 'my_index',
        'type' => 'my_type',
        'id' => $item['id'],
        'body' => [
            'brand'             => $item['brand'],
            'color'             => $item['color'],
            'category'          => $item['category'],
        ]
    ];

    $client->index($params);
}

$params = [
    'index' => 'my_index',
    'body' => [
        'query' => [
            'bool' => [
                'must' => [
                    [ 'match' => [ 'brand' => 'tommy' ] ],
                    [ 'match' => [ 'color' => 'grey' ] ]
                ]
            ]
        ],
        'aggs' => [
            'brands' => [
                'terms' => [
                    'field' => 'brand.keyword',
                ],
            ],
            'colors' => [
                'terms' => [
                    'field' => 'color.keyword',
                ]
            ],
            'categories' => [
                'terms' => [
                    'field' => 'category.keyword',
                ]
            ]
        ]
    ]
];

$response = $client->search($params);
print_r($response);
Array
(
    [brands] => Array
        (
            [doc_count_error_upper_bound] => 0
            [sum_other_doc_count] => 0
            [buckets] => Array
                (
                    [0] => Array
                        (
                            [key] => Tommy Jeans
                            [doc_count] => 3
                        )

                    [1] => Array
                        (
                            [key] => Tommy Hilfiger
                            [doc_count] => 1
                        )

                )

        )

    [categories] => Array
        (
            [doc_count_error_upper_bound] => 0
            [sum_other_doc_count] => 0
            [buckets] => Array
                (
                    [0] => Array
                        (
                            [key] => Sneakers
                            [doc_count] => 2
                        )

                    [1] => Array
                        (
                            [key] => Shirts
                            [doc_count] => 1
                        )

                    [2] => Array
                        (
                            [key] => Trousers
                            [doc_count] => 1
                        )

                )

        )

    [colors] => Array
        (
            [doc_count_error_upper_bound] => 0
            [sum_other_doc_count] => 0
            [buckets] => Array
                (
                    [0] => Array
                        (
                            [key] => Grey
                            [doc_count] => 4
                        )

                )

        )

)