我是弹性搜索的新手,我很累在索引文档中查找数据。就像我有4个文档,并且在2个字段中fullName, userName
-
{
"_index": "users",
"_type": "users",
"_id": "NwV2GG8BmEFrScbl3IE8",
"_score": 1,
"_source": {
"fullName": "Max Payne",
"id": 1,
"userName": "MaxP"
}
},
{
"_index": "users",
"_type": "users",
"_id": "MgV2GG8BmEFrScbl3IE8",
"_score": 1,
"_source": {
"fullName": "Thomas John",
"id": 6,
"userName": "ThomesJ"
}
},
{
"_index": "users",
"_type": "users",
"_id": "MgD2TG1BmEFrrfbs3RT9",
"_score": 1,
"_source": {
"fullName": "John well",
"id": 7,
"userName": "ThomesW"
}
},
{
"_index": "users",
"_type": "users",
"_id": "QwR58DTBmEFrScbl8op4",
"_score": 1,
"_source": {
"fullName": "Max smith",
"id": 1,
"userName": "MaxS"
}
}
如果搜索 情况1 “马”然后我需要3个文档
案例2 'Max',那么我需要2个文档
案例3 'Max s',那么我需要1个文档(Max Smith) “ Max p”,那么我需要1个文档(Max Payne)
情况4 '约翰',那我需要2个文件
我尝试使用此方法,如果完整字符串匹配,则找到数据,否则找不到数据。
"bool" : {
"should": {
"query_string": {
"query": '*'+keyword+'*', // "query": keyword+'*',
"fields": [ "fullName", "userName" ]
},
},
}
此外,我尝试了一下,但没有用
"term": {
"fullName": {
"value": keyword
}
}
我将Elasticsearch 6.3
用于NodeJs客户端
答案 0 :(得分:0)
Elasticsearch的工作原理与您在这里可能期望的根本不同。使用您使用的默认分析器,索引字段中的每个单词都成为可搜索的令牌。
使用通配符查询(https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html)可以按令牌的一部分进行搜索。但是,强烈建议不要盲目使用通配符查询,因为它们不能随着索引的增长而很好地扩展。
如果绝对需要按您描述的那样按令牌的一部分进行搜索,则应检出 n-gram 令牌过滤器(https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-ngram-tokenfilter.html)。 这会产生类似[m,a,x,ma,ax]的标记,使您可以搜索“ ma”。 这是一个实现ngram-filter的示例:
PUT so_example
{
"settings": {
"analysis": {
"analyzer": {
"ngram-example": {
"tokenizer": "standard",
"filter": [
"ngram"
]
}
}
}
},
"mappings": {
"users": {
"properties": {
"userName": {
"type": "text",
"analyzer": "ngram-example"
},
"fullName": {
"type": "text",
"analyzer": "ngram-example"
}
}
}
}
}
这将允许您像执行搜索一样
GET so_example/_search
{
"query": {
"multi_match": {
"query": "Max Pa",
"type": "phrase",
"fields": [
"fullName"
]
}
}
}
对于以“ Max P”为例的示例,请记住要搜索2个令牌,因为从技术上讲它们是2个单词。要搜索需要以给定顺序排列的令牌,您需要 phrase_match 查询(https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html)。否则,搜索词P不需要在搜索字段中跟随Max。
答案 1 :(得分:0)
您需要尝试此查询并根据您的不同情况使用通配符,您将获得所需的预期结果
{
"query": {
"wildcard": {
"fullName": {
"value": "keyword"
}
}
}
}
对于情况1:“值”:“ * ma *” 情况2:“ value”:“ max”,并且类似。
希望这会有所帮助。
答案 2 :(得分:0)
使用一个名为“ search_name
”的新属性,其中将存储用户名和全名。 'copy_to
'将有助于实现这一目标。
按如下所示更改索引-
PUT user_index
{
"settings": {
"number_of_shards": 1,
"analysis": {
"filter": {
"edge_filter": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 50
}
},
"analyzer": {
"lowercase": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"trim",
"lowercase"
]
},
"userName_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"edge_filter"
]
},
"fullName_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"edge_filter"
]
}
}
}
},
"mappings": {
"properties": {
"userName": {
"type": "text",
"analyzer": "userName_analyzer",
"search_analyzer": "standard",
"copy_to": "search_name"
},
"fullName": {
"type": "text",
"analyzer": "fullName_analyzer",
"search_analyzer": "standard",
"copy_to": "search_name"
},
"search_name":{
"type": "text",
"analyzer": "fullName_analyzer",
"search_analyzer": "standard"
}
}
}
}
现在使用如下所示的搜索查询-
GET user_index/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"search_name":{
"query": "max p",
"operator" : "and"
}
}
}
]
}
}
}
请根据给出的要求更改查询值。 希望这会有所帮助。