gpt4 book ai didi

elasticsearch - 如何在 Elasticsearch 中获取每学期的统计信息

转载 作者:行者123 更新时间:2023-12-04 03:36:54 25 4
gpt4 key购买 nike

我需要执行以下操作(在后端):用户键入查询并返回命中以及命中的统计信息。下面是一个简化的例子。

假设查询是Grif,然后用户返回(例如随机词)

  • 格里菲斯
  • 格里芬
  • 格里夫
  • 赠送
  • 狮鹫

以及某个术语出现的频率+文档数量,例如:

  • Griffith(频率 10,3 篇文档)
  • Griffin(频率 17、9 篇文档)
  • Grif(频率 6、3 个文档)
  • Grift(频率 9、5 个文档)
  • Griffins(频率 11,4 个文档)

我是 Elasticsearch 的新手,所以我不确定从哪里开始实现类似的东西。什么类型的查询最适合这个?我可以用什么来获得这种统计数据?任何其他建议也将不胜感激。

最佳答案

这有多个层次。你需要:

  • n-gram/部分/搜索类型匹配
  • 一种按原始形式对匹配关键字进行分组的方法
  • 一种反向查找文档和术语频率的机制。

我不知道有什么方法可以一次实现这一目标,但这是我的看法。

  1. 您可以从一个特殊的、支持 n-gram 的分析器开始,如 in my other answer 所解释的那样.有原始的 content 字段,加上一个 multi-field mapping对于上述分析器,加上一个 keyword 字段以聚合在线下:
PUT my-index
{
"settings": {
"index": {
"max_ngram_diff": 20
},
"analysis": {
"tokenizer": {
"my_ngrams": {
"type": "ngram",
"min_gram": 3,
"max_gram": 20,
"token_chars": [
"letter",
"digit"
]
}
},
"analyzer": {
"my_ngrams_analyzer": {
"tokenizer": "my_ngrams",
"filter": [
"lowercase"
]
}
}
}
},
"mappings": {
"properties": {
"content": {
"type": "text",
"fields": {
"analyzed": {
"type": "text",
"analyzer": "my_ngrams_analyzer"
},
"keyword": {
"type": "keyword"
}
}
}
}
}
}
  1. 接下来,在 content 字段中批量插入一些包含文本的示例文档。请注意,每个文档也有一个 _id - 稍后您将需要它们。
POST _bulk
{"index":{"_index":"my-index", "_id":1}}
{"content":"Griffith"}
{"index":{"_index":"my-index", "_id":2}}
{"content":"Griffin"}
{"index":{"_index":"my-index", "_id":3}}
{"content":"Grif"}
{"index":{"_index":"my-index", "_id":4}}
{"content":"Grift"}
{"index":{"_index":"my-index", "_id":5}}
{"content":"Griffins"}
{"index":{"_index":"my-index", "_id":6}}
{"content":"Griffith"}
{"index":{"_index":"my-index", "_id":7}}
{"content":"Griffins"}
  1. .analyzed 字段中搜索n-gram,并通过terms aggregation 将匹配的文档按原始术语分组。 .同时,通过 top_hits aggregation 检索其中一个分桶文档的 _id .顺便说一句 — 在给定的桶中返回哪个 _id 并不重要 — 所有都将包含相同的桶项。
POST my-index/_search?filter_path=aggregations.*.buckets.key,aggregations.*.buckets.doc_count,aggregations.*.buckets.*.hits.hits._id
{
"size": 0,
"query": {
"term": {
"content.analyzed": "grif"
}
},
"aggs": {
"full_terms": {
"terms": {
"field": "content.keyword",
"size": 10
},
"aggs": {
"top_doc": {
"top_hits": {
"size": 1,
"_source": false
}
}
}
}
}
}
  1. 观察 react 。先前请求的 filter_path URL 参数减少了对我们需要的那些属性的响应——未触及的原始 full_terms 加上底层的一个 ID:
{
"aggregations" : {
"full_terms" : {
"buckets" : [
{
"key" : "Griffins",
"doc_count" : 2,
"top_doc" : {
"hits" : {
"hits" : [
{
"_id" : "5"
}
]
}
}
},
{
"key" : "Griffith",
"doc_count" : 2,
"top_doc" : {
"hits" : {
"hits" : [
{
"_id" : "1"
}
]
}
}
},
{
"key" : "Grif",
"doc_count" : 1,
"top_doc" : {
"hits" : {
"hits" : [
{
"_id" : "3"
}
]
}
}
},
{
"key" : "Griffin",
"doc_count" : 1,
"top_doc" : {
"hits" : {
"hits" : [
{
"_id" : "2"
}
]
}
}
},
{
"key" : "Grift",
"doc_count" : 1,
"top_doc" : {
"hits" : {
"hits" : [
{
"_id" : "4"
}
]
}
}
}
]
}
}
}

有趣的部分时间到了。

有一个名为 Term Vectors 的专用 Elasticsearch API它完全您所追求的——它从整个索引中检索字段和术语统计信息。为了将这些统计数据交给您,它需要文档 ID——您将从上述聚合中获得这些 ID!

  1. 最后,由于您有多个术语向量可以使用,您可以使用 Multi term vectors API像这样——再次通过 filter_path 压缩响应:
POST /my-index/_mtermvectors?filter_path=docs.term_vectors.*.*.*.doc_freq,docs.term_vectors.*.*.*.term_freq
{
"docs": [
{
"_id": "5", <--- guaranteeing
"fields": [
"content.keyword"
],
"payloads": false,
"positions": false,
"offsets": false,
"field_statistics": false,
"term_statistics": true
},
{
"_id": "1", <--- the response
"fields": [
"content.keyword"
],
"payloads": false,
"positions": false,
"offsets": false,
"field_statistics": false,
"term_statistics": true
},
{
"_id": "3", <--- order
"fields": [
"content.keyword"
],
"payloads": false,
"positions": false,
"offsets": false,
"field_statistics": false,
"term_statistics": true
},
{
"_id": "2",
"fields": [
"content.keyword"
],
"payloads": false,
"positions": false,
"offsets": false,
"field_statistics": false,
"term_statistics": true
},
{
"_id": "4",
"fields": [
"content.keyword"
],
"payloads": false,
"positions": false,
"offsets": false,
"field_statistics": false,
"term_statistics": true
}
]
}
  1. 结果可以在您的后端进行后处理以形成您的自动完成响应。您有 A) 完整的术语,B) 匹配文档的数量 (doc_freq),以及 C),术语频率:
{
"docs" : [
{
"term_vectors" : {
"content.keyword" : {
"terms" : {
"Griffins" : { | term
"doc_freq" : 2, | <-- # of docs
"term_freq" : 1 | term frequency
}
}
}
}
},
{
"term_vectors" : {
"content.keyword" : {
"terms" : {
"Griffith" : {
"doc_freq" : 2,
"term_freq" : 1
}
}
}
}
},
{
"term_vectors" : {
"content.keyword" : {
"terms" : {
"Grif" : {
"doc_freq" : 1,
"term_freq" : 1
}
}
}
}
},
{
"term_vectors" : {
"content.keyword" : {
"terms" : {
"Griffin" : {
"doc_freq" : 1,
"term_freq" : 1
}
}
}
}
},
{
"term_vectors" : {
"content.keyword" : {
"terms" : {
"Grift" : {
"doc_freq" : 1,
"term_freq" : 1
}
}
}
}
}
]
}

无耻插件:如果您是 Elasticsearch 的新手,并且像我一样,从真实世界的示例中学习最好,请考虑购买 my Elasticsearch Handbook .

关于elasticsearch - 如何在 Elasticsearch 中获取每学期的统计信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66711054/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com