当前位置: 首页 > 面试题库 >

ElasticSearch聚合+在非数值字段5.3上排序

子车安和
2023-03-14
问题内容

我想将数据汇总到另一个字段中,也想根据名称以排序方式获取汇总数据。

我的数据是:

{
    "_index": "testing-aggregation",
    "_type": "employee",
    "_id": "emp001_local000000000000001",
    "_score": 10.0,
    "_source": {
        "name": [
            "Person 01"
        ],
        "groupbyid": [
            "group0001"
        ],
        "ranking": [
             "2.0"
        ]
    }
},
{
    "_index": "testing-aggregation",
    "_type": "employee",
    "_id": "emp002_local000000000000001",
    "_score": 85146.375,
    "_source": {
        "name": [
            "Person 02"
        ],
        "groupbyid": [
            "group0001"
        ],
        "ranking": [
             "10.0"
        ]
    }
},
{
    "_index": "testing-aggregation",
    "_type": "employee",
    "_id": "emp003_local000000000000001",
    "_score": 20.0,
    "_source": {
        "name": [
            "Person 03"
        ],
        "groupbyid": [
            "group0002"
        ],        
        "ranking": [
             "-1.0"
        ]
    }
},
{
    "_index": "testing-aggregation",
    "_type": "employee",
    "_id": "emp004_local000000000000001",
    "_score": 5.0,
    "_source": {
        "name": [
            "Person 04"
        ],
        "groupbyid": [
            "group0002"
        ],
        "ranking": [
             "2.0"
        ]
    }
}

我的查询:

{
    "size": 0,
    "query": {
        "bool": {
            "must": [
                {
                    "query_string": {
                        "query": "name:emp*^1000.0"
                    }
                }
            ]
        }
    },
    "aggs": {
        "groupbyid": {
            "terms": {
                "field": "groupbyid.raw",
                "order": {
                    "top_hit_agg": "desc"
                },
                "size": 10
            },
            "aggs": {
                "top_hit_agg": {
                    "terms": {
                        "field": "name"
                    }
                }
            }
        }
    }
}

我的映射是:

{
    "name": {
        "type": "text",
        "fielddata": true,
        "fields": {
            "lower_case_sort": {
                "type": "text",
                "fielddata": true,
                "analyzer": "case_insensitive_sort"
            }
        }
    },
    "groupbyid": {
        "type": "text",
        "fielddata": true,
        "index": "analyzed",
        "fields": {
            "raw": {
                "type": "keyword",
                "index": "not_analyzed"
            }
        }
    }
}

我正在根据分组记录的相关性平均值来获取数据。现在,我想要的是第一个基于groupid的记录,然后在每个存储桶中根据名称字段对数据进行排序。

我想对一个字段进行分组,然后在对分区进行分组之后,对另一个字段进行排序。这是样本数据。

还有其他字段,例如created_on,updated_on。我还想获得基于该字段的排序数据。还按字母顺序获取数据。

我想对非数字数据类型(字符串)进行排序。我可以做数字数据类型。

我可以为排名字段执行此操作,但不能为名称字段执行此操作。它给出了以下错误。

Expected numeric type on field [name], but got [text];

问题答案:

您要问几件事,所以我将尝试依次回答。

步骤1:按相关性对存储桶进行排序

我正在根据分组记录的相关性平均值来获取数据。

如果这是您要尝试执行的操作,则不是您编写的聚合正在执行的操作。术语汇总默认情况下按每个存储区中的文档数降序对存储区进行排序。要按“平均相关性”(我将其解释为“
_score组中文档的平均”)对组进行排序,您需要在得分上添加一个子聚合,并按此对术语聚合进行排序:

"aggregations": {
  "most_relevant_groups": {
    "terms": {
      "field": "groupbyid.raw",
      "order": {
        "average_score": "desc"
      }
    },
    "aggs": {
      "average_score": {
        "avg": {
          "script": {
            "inline": "_score",
            "lang": "painless",
          }
        }
      }
    }
  }
}

步骤2:按姓名对员工进行排序

现在,我想要的是第一个基于groupid的记录,然后在每个存储桶中根据名称字段对数据进行排序。

要对每个存储桶中的文档进行排序,可以使用top_hits聚合:

"aggregations": {
  "most_relevant_groups": {
    "terms": {
      "field": "groupbyid.raw",
      "order": {
        "average_score": "desc"
      }
    },
    "aggs": {
      "employees": {
        "top_hits": {
          "size": 10,  // Default will be 10 - change to whatever
          "sort": [
            {
              "name.lower_case_sort": {
                "order": "asc"
              }
            }
          ]
        }
      }
    }
  }
}

步骤3:将所有内容放在一起

将以上两者放在一起,以下聚合将满足您的需求(请注意,我使用了function_score查询来基于排名模拟“相关性”-您的查询可以是任意查询,而只要是能够产生所需相关性的查询即可)

POST /testing-aggregation/employee/_search
{
  "size": 0,
  "query": {
    "function_score": {
      "functions": [
        {
          "field_value_factor": {
            "field": "ranking"
          }
        }
      ]
    }
  },
  "aggs": {
    "groupbyid": {
      "terms": {
        "field": "groupbyid.raw",
        "size": 10,
        "order": {
          "average_score": "desc"
        }
      },
      "aggs": {
        "average_score": {
          "avg": {
            "script": {
              "inline": "_score",
              "lang": "painless"
            }
          }
        },
        "employees": {
          "top_hits": {
            "size": 10,
            "sort": [
              {
                "name.lower_case_sort": {
                  "order": "asc"
                }
              }
            ]
          }
        }
      }
    }
  }
}


 类似资料:
  • 在这里,我得到了错误: “无效的术语聚合顺序路径[price>price>price.max]。术语桶只能在子聚合器路径上排序,该路径由路径中的零个或多个单桶聚合和路径末尾的最终单桶或度量聚合组成。子路径[price]指向非单桶聚合” 如果我按持续时间聚合排序,查询可以正常工作,如 那么,有什么方法可以通过嵌套字段上的嵌套聚合来排序聚合吗?

  • 问题内容: 我想在字段上使用stats或extended_stats聚合,但是找不到完成此操作的任何示例(即,似乎只能将聚合与实际文档字段一起使用)。 是否有可能计算出“元数据”在ElasticSearch查询响应每个命中字段请求集合(例如,,,,等等)? 我假设答案是“否”,因为未对类似字段进行索引… 问题答案: 注意:就最新版本的Elasticsearch而言,原始答案现在已过时。使用Groo

  • 在elasticsearch中,我可以在第二个聚合的数字字段上聚合和排序聚合。 例如。 但是,我想根据分类字段值对聚合进行排序。也就是说,字段2的值是(“a”、“b”、“c”)中的一个值——我想首先按所有文档对a1进行排序,字段2为:“a”,然后字段2为“b”,最后字段2为“c”。 在我的例子中,每个字段1都有一个唯一的字段2。所以我真的只想找到一种方法,按字段2对a1结果进行排序。

  • 问题内容: 我将此数据插入了Elasticsearch: 旁注:重现: 1)下载:http://wmo.co/20160928_es_query/bulk.json 2)执行:卷曲-s -XPOST ‘ 的http://本地主机:9200 /测试/外部/ _bulk漂亮 ‘ -数据二进制@ bulk.json 问题: 获取每个“位置”有多少记录的计数。 解决方案1:存储桶聚合..没有得到期望的结果

  • 我是Elasticsearch的新手,我希望在Elasticsearch 5的字段上执行某些聚合。x索引。我有一个索引,其中包含带有字段(具有嵌套结构)和字段(具有嵌套结构)的文档。这些是动态映射的字段。以下是示例文档 文件2: DOC 3: 我想在langs字段上执行总和聚合,这样对于每个键(X/Y)和每种语言,我都可以获得索引中所有文档的总和。此外,我还想从docLang字段生成每种语言类型的

  • 问题内容: 我正在尝试创建一个脚本字段,该脚本字段将计算两个时间戳之间的时间差,然后在该脚本字段上聚合一个。 我首先尝试: 在合计平均值下产生价值。 然后我尝试了: 生成了一条错误消息,内容为:“在映射中找不到[timedifference]的字段” 问题答案: 简单地将脚本移到聚合上怎么样?