如何使用 Elasticsearch 搜索给定字段的所有唯一值?
我有select full_name from authors
这样的查询,所以我可以在表单上向用户显示列表。
答案 0 :(得分:18)
您可以在'full_name'字段中设置terms facet。但是为了正确地执行此操作,您需要确保在索引时不对其进行标记,否则构面中的每个条目都将是字段内容的一部分。您很可能需要在映射中将其配置为“not_analyzed”。如果您还在搜索它并且仍想要对其进行标记,则可以使用multi field以两种不同的方式对其进行索引。
您还需要考虑到,取决于属于full_name字段的唯一术语的数量,此操作可能很昂贵并且需要相当多的内存。
答案 1 :(得分:12)
对于Elasticsearch 1.0及更高版本,您可以利用terms aggregation
执行此操作,
查询DSL:
{
"aggs": {
"NAME": {
"terms": {
"field": "",
"size": 10
}
}
}
}
一个真实的例子:
{
"aggs": {
"full_name": {
"terms": {
"field": "authors",
"size": 0
}
}
}
}
然后,您可以获得authors
字段的所有唯一值。
size = 0表示不限制术语数(这要求es为1.1.0或更高版本。)
响应:
{
...
"aggregations" : {
"full_name" : {
"buckets" : [
{
"key" : "Ken",
"doc_count" : 10
},
{
"key" : "Jim Gray",
"doc_count" : 10
},
]
}
}
}
答案 2 :(得分:4)
现有答案在Elasticsearch 5.X中对我不起作用,原因如下:
"size": 0
无法解析,因为“[size]必须大于0。”full_name
字段。但是,未分析的keyword
字段可用于聚合。 解决方案1 :使用Scroll API。它的工作原理是保留搜索上下文并发出多个请求,每次返回后续批次的结果。如果您使用的是Python,则elasticsearch模块会使用scan()
helper function来处理您的滚动并返回所有结果。
解决方案2 :使用Search After API。它与Scroll类似,但提供实时光标而不是保留搜索上下文。因此,它对于实时请求更有效。
答案 3 :(得分:2)
<强>直觉:强> 用SQL术语:
Select distinct full_name from authors;
相当于
Select full_name from authors group by full_name;
因此,我们可以使用ElasticSearch中的分组/聚合语法来查找不同的条目。
假设以下是弹性搜索中存储的结构:
[{
"author": "Brian Kernighan"
},
{
"author": "Charles Dickens"
}]
什么行不通:普通汇总
{
"aggs": {
"full_name": {
"terms": {
"field": "author"
}
}
}
}
我收到以下错误:
{
"error": {
"root_cause": [
{
"reason": "Fielddata is disabled on text fields by default...",
"type": "illegal_argument_exception"
}
]
}
}
什么像魅力一样:在字段中附加 .keyword
{
"aggs": {
"full_name": {
"terms": {
"field": "author.keyword"
}
}
}
}
示例输出可能是:
{
"aggregations": {
"full_name": {
"buckets": [
{
"doc_count": 372,
"key": "Charles Dickens"
},
{
"doc_count": 283,
"key": "Brian Kernighan"
}
],
"doc_count": 1000
}
}
}
奖金提示:
让我们假设有问题的字段嵌套如下:
[{
"authors": [{
"details": [{
"name": "Brian Kernighan"
}]
}]
},
{
"authors": [{
"details": [{
"name": "Charles Dickens"
}]
}]
}
]
现在正确的查询变为:
{
"aggregations": {
"full_name": {
"aggregations": {
"author_details": {
"terms": {
"field": "authors.details.name"
}
}
},
"nested": {
"path": "authors.details"
}
}
},
"size": 0
}
答案 4 :(得分:1)
为Elasticsearch 5.2.2工作
curl -XGET http://localhost:9200/articles/_search?pretty -d '
{
"aggs" : {
"whatever" : {
"terms" : { "field" : "yourfield", "size":10000 }
}
},
"size" : 0
}'
"size":10000
表示获取(最多)10000个唯一值。如果没有这个,如果您有超过10个唯一值,则只返回10个值。
"size":0
表示结果中"hits"
不包含任何文件。默认情况下,返回10个文档,我们不需要这些文档。
另请注意,根据this page,facet已被Elasticsearch 1.0中的聚合所取代,它们是facet的超集。