elasticsearch 使用弹性搜索自动完成功能,elasticsearch,autocomplete,elasticsearch,Autocomplete" /> elasticsearch 使用弹性搜索自动完成功能,elasticsearch,autocomplete,elasticsearch,Autocomplete" />

elasticsearch 使用弹性搜索自动完成功能

elasticsearch 使用弹性搜索自动完成功能,elasticsearch,autocomplete,elasticsearch,Autocomplete,我有一个包含以下文档的弹性搜索索引,我希望在指定字段上具有自动完成功能: 映射: 用例: 我的查询是形式前缀类型的,例如“sta”、“star”、“star w”、“start war”等,另外还有一个过滤器,如tags=“scientific”。此外,这些查询还可以匹配其他字段,如description、actors(在cast字段中,不是嵌套的)。我还想知道它与哪个字段匹配 我调查了两种方法,但没有一种方法能够解决上述用例: 1) 建议者自动完成: 这样看来,我必须添加另一个名为“建议”的

我有一个包含以下文档的弹性搜索索引,我希望在指定字段上具有自动完成功能:

映射:

用例:

我的查询是形式前缀类型的,例如“sta”、“star”、“star w”、“start war”等,另外还有一个过滤器,如tags=“scientific”。此外,这些查询还可以匹配其他字段,如description、actors(在cast字段中,不是嵌套的)。我还想知道它与哪个字段匹配

我调查了两种方法,但没有一种方法能够解决上述用例:

1) 建议者自动完成:

这样看来,我必须添加另一个名为“建议”的字段来复制不需要的数据

2) 使用前缀筛选器/查询:

这将返回整个文档,而不是精确匹配的术语


是否有一种干净的方法可以实现这一点,请告知。

不要单独创建映射,直接将数据插入索引。它将为此创建默认映射。使用下面的查询自动完成

GET /netflix/movie/_search
{
"query": {
    "query_string": {
        "query": "sta*"
    }
  }
}

不要单独创建映射,直接将数据插入索引。它将为此创建默认映射。使用下面的查询自动完成

GET /netflix/movie/_search
{
"query": {
    "query_string": {
        "query": "sta*"
    }
  }
}

我认为,
completion suggester
将是最干净的方式,但如果这是不可取的,您可以在name字段上使用

这是一个样本索引(我假设您使用的是您问题中的ES 1.7

PUT netflix
{
  "settings": {
    "analysis": {
      "analyzer": {
        "prefix_analyzer": {
          "tokenizer": "keyword",
          "filter": [
            "lowercase",
            "trim",
            "edge_filter"
          ]
        },
        "keyword_analyzer": {
          "tokenizer": "keyword",
          "filter": [
            "lowercase",
            "trim"
          ]
        }
      },
      "filter": {
        "edge_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 20
        }
      }
    }
  },
  "mappings": {
    "movie":{
      "properties": {
        "name":{
          "type": "string",
          "fields": {
            "prefix":{
            "type":"string",
            "index_analyzer" : "prefix_analyzer",
            "search_analyzer" : "keyword_analyzer"
            },
            "raw":{
              "type": "string",
              "analyzer": "keyword_analyzer"
            }
          }
        },
        "tags":{
          "type": "string", "index": "not_analyzed"
        }
      }
    }
  }
}
使用时,将以不同的方式分析名称字段。name.prefix与一起使用 因此,可以将字符串星战分解为s、st、sta等。但在搜索时,使用关键字_分析器,以便搜索查询不会分解为多个小标记。name.raw将用于聚合

下面的查询将给出前10条建议

GET netflix/movie/_search
{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "tags": "sci-fi"
        }
      },
      "query": {
        "match": {
          "name.prefix": "sta"
        }
      }
    }
  },
  "size": 0,
  "aggs": {
    "unique_movie_name": {
      "terms": {
        "field": "name.raw",
        "size": 10
      }
    }
  }
}
结果会是这样的

"aggregations": {
      "unique_movie_name": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": "star trek",
               "doc_count": 1
            },
            {
               "key": "star wars",
               "doc_count": 1
            }
         ]
      }
   }
更新

我想,你可以使用这个功能。突出显示部分将获得整个单词以及匹配的字段。你也可以在其中使用和突出显示来获得嵌套文档

{
  "query": {
    "query_string": {
      "query": "sta*"
    }
  },
  "_source": false,
  "highlight": {
    "fields": {
      "*": {}
    }
  }
}

我认为,
completion suggester
将是最干净的方式,但如果这是不可取的,您可以在name字段上使用

这是一个样本索引(我假设您使用的是您问题中的ES 1.7

PUT netflix
{
  "settings": {
    "analysis": {
      "analyzer": {
        "prefix_analyzer": {
          "tokenizer": "keyword",
          "filter": [
            "lowercase",
            "trim",
            "edge_filter"
          ]
        },
        "keyword_analyzer": {
          "tokenizer": "keyword",
          "filter": [
            "lowercase",
            "trim"
          ]
        }
      },
      "filter": {
        "edge_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 20
        }
      }
    }
  },
  "mappings": {
    "movie":{
      "properties": {
        "name":{
          "type": "string",
          "fields": {
            "prefix":{
            "type":"string",
            "index_analyzer" : "prefix_analyzer",
            "search_analyzer" : "keyword_analyzer"
            },
            "raw":{
              "type": "string",
              "analyzer": "keyword_analyzer"
            }
          }
        },
        "tags":{
          "type": "string", "index": "not_analyzed"
        }
      }
    }
  }
}
使用时,将以不同的方式分析名称字段。name.prefix与一起使用 因此,可以将字符串星战分解为s、st、sta等。但在搜索时,使用关键字_分析器,以便搜索查询不会分解为多个小标记。name.raw将用于聚合

下面的查询将给出前10条建议

GET netflix/movie/_search
{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "tags": "sci-fi"
        }
      },
      "query": {
        "match": {
          "name.prefix": "sta"
        }
      }
    }
  },
  "size": 0,
  "aggs": {
    "unique_movie_name": {
      "terms": {
        "field": "name.raw",
        "size": 10
      }
    }
  }
}
结果会是这样的

"aggregations": {
      "unique_movie_name": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": "star trek",
               "doc_count": 1
            },
            {
               "key": "star wars",
               "doc_count": 1
            }
         ]
      }
   }
更新

我想,你可以使用这个功能。突出显示部分将获得整个单词以及匹配的字段。你也可以在其中使用和突出显示来获得嵌套文档

{
  "query": {
    "query_string": {
      "query": "sta*"
    }
  },
  "_source": false,
  "highlight": {
    "fields": {
      "*": {}
    }
  }
}


感谢您的回复,但这将返回整个文档,如果只返回该文档中的术语,因为标记将是一个很长的列表。您是否可以在用户搜索时共享您的映射?您想只显示搜索术语数据吗?要同时显示搜索术语及其匹配的字段。再次感谢。感谢您的回复,但这将返回whole document,将该文档中的术语作为标记返回会是一个很长的列表。当用户搜索时,您是否可以共享您的映射?您想只显示搜索术语数据..?需要搜索术语和匹配的字段。再次感谢。非常感谢您的解决方案。这是完整的映射:,是否有方法返回哪个f使用您的解决方案或任何其他方式匹配的ield(也有嵌套字段)作为结果的一部分。再次感谢!要求是什么?想要建议结果(自动完成)或想要知道用户查询匹配的字段吗?我以为您想要自动完成电影名称字段。想要建议结果(自动完成)并且还知道建议来自哪个领域,建议可以来自电影名称,也可以来自演员名称、描述等,因此在自动建议中,建议显示为实体,例如:query=“ar”,结果1)“arnold schwarzenegger”作为实体演员(匹配演员名称)2)电影《天方夜谭》(与电影名称匹配)。我真的很感谢你的帮助。我已经更新了答案。如果你还需要帮助,请告诉我。非常感谢你的帮助。亮点应该有用,我会试试看!非常感谢您的解决方案。这是完整的映射:,是否有方法使用您的解决方案或任何其他方法返回匹配的字段(它也有嵌套字段),作为结果的一部分。再次非常感谢!要求是什么?想建议结果(自动完成)或想知道用户查询匹配的字段?我以为你想自动完成电影名称字段。如果你想建议结果(自动完成),还想知道建议来自哪个字段,建议可以来自电影名称,也可以来自演员姓名、描述等,因此在自动建议中,建议显示为该实体的内容,例如:query=“ar”,结果是1)“阿诺德·施瓦辛格”作为实体演员(与演员名称匹配)2)天方夜谭作为电影(与电影名称匹配)。我真的很感谢你的帮助。我已经更新了答案。如果你还需要帮助,请告诉我。非常感谢你的帮助。亮点应该有用,我会试试看!