1

我在我的项目中使用FOSElasticaBundleSymfony2,并且 MySQL 数据库上有条目和用户表,每个条目属于一个用户。

我想在数据库的所有条目中为每个用户获取一个条目。

参赛作品表示

[
  {
    "id": 1,
    "name": "Hello world",
    "user": {
      "id": 17,
      "username": "foo"
    }
  },
  {
    "id": 2,
    "name": "Lorem ipsum",
    "user": {
      "id": 15,
      "username": "bar"
    }
  },
  {
    "id": 3,
    "name": "Dolar sit amet",
    "user": {
      "id": 17,
      "username": "foo"
    }
  },
]

预期结果是:

[
  {
    "id": 1,
    "name": "Hello world",
    "user": {
      "id": 17,
      "username": "foo"
    }
  },
  {
    "id": 2,
    "name": "Lorem ipsum",
    "user": {
      "id": 15,
      "username": "bar"
    }
  }
]

但它返回表上的所有条目。我尝试将聚合添加到我的弹性搜索查询中,但没有任何改变。

$distinctAgg = new \Elastica\Aggregation\Terms("distinctAgg");
$distinctAgg->setField("user.id");
$distinctAgg->setSize(1);

$query->addAggregation($distinctAgg);

有没有办法通过术语过滤器或其他方法来做到这一点?任何帮助都会很棒。谢谢你。

4

1 回答 1

2

当您习惯 MySQL group by 时,聚合并不容易理解。

首先,聚合结果不是在中返回hits,而是在 中返回aggregations。因此,当您获得搜索结果时,您必须获得这样的聚合:

$results = $search->search();
$aggregationsResults = $results->getAggregations();

第二件事是聚合不会返回你的来源。通过您的示例的聚合,您将只知道您有 1 个 ID 为 15 的用户和 2 个 ID 为 15 的用户。

例如,使用此查询:

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "byUser": {
      "terms": {
        "field": "user.id"
      }
    }
  }
}

结果:

{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 3,
      "max_score": 1,
      "hits": [ ... ]
   },
   "aggregations": {
      "byUser": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": 17,
               "doc_count": 2
            },
            {
               "key": 15,
               "doc_count": 1
            }
         ]
      }
   }
}

如果你想得到结果,就像在 MySQL 中使用 GROUP BY 一样,你必须使用top_hits子聚合:

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "byUser": {
      "terms": {
        "field": "user.id"
      },
      "aggs": {
        "results": {
          "top_hits": {
            "size": 1
          }
        }
      }
    }
  }
}

结果:

{
   "took": 3,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 3,
      "max_score": 1,
      "hits": [ ... ]
   },
   "aggregations": {
      "byUser": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": 17,
               "doc_count": 2,
               "results": {
                  "hits": {
                     "total": 2,
                     "max_score": 1,
                     "hits": [
                        {
                           "_index": "test_stackoverflow",
                           "_type": "test1",
                           "_id": "1",
                           "_score": 1,
                           "_source": {
                              "id": 1,
                              "name": "Hello world",
                              "user": {
                                 "id": 17,
                                 "username": "foo"
                              }
                           }
                        }
                     ]
                  }
               }
            },
            {
               "key": 15,
               "doc_count": 1,
               "results": {
                  "hits": {
                     "total": 1,
                     "max_score": 1,
                     "hits": [
                        {
                           "_index": "test_stackoverflow",
                           "_type": "test1",
                           "_id": "2",
                           "_score": 1,
                           "_source": {
                              "id": 2,
                              "name": "Lorem ipsum",
                              "user": {
                                 "id": 15,
                                 "username": "bar"
                              }
                           }
                        }
                     ]
                  }
               }
            }
         ]
      }
   }
}

此页面上的更多信息:https ://www.elastic.co/blog/top-hits-aggregation

于 2015-05-22T14:31:12.357 回答