首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Elasticsearch 6.8中,模糊搜索(如MySQL中的'%aaa%‘)的最佳实践是什么

在Elasticsearch 6.8中,模糊搜索(如MySQL中的'%aaa%‘)的最佳实践是什么
EN

Stack Overflow用户
提问于 2020-09-16 10:51:28
回答 1查看 428关注 0票数 0

背景:我使用Mysql,有数百万的数据,每行有20列,我们有一些复杂的搜索和一些列使用模糊匹配,例如username like '%aaa%',它不能使用mysql索引,除非删除第一个%,但是我们需要模糊匹配来做类似Satckoverflow搜索的搜索,我也检查了Mysqlfulltext index,但如果使用其他索引,它不支持在一个sql中进行复杂的搜索。

我的解决方案是:添加Elasticsearch作为我们的搜索引擎,在Mysql和Es中插入数据,只在Elasticsearch中搜索数据

我查了Elasticsearch模糊搜索wildcard有效,但许多人不建议使用*在单词开头,它会使搜索变得非常慢。

例如:用户名:'John_雪‘wildcard有效,但可能非常慢

代码语言:javascript
复制
GET /user/_search
{
  "query": {
    "wildcard": {
      "username": "*hn*"
    }
  }
}

match_phrase不起作用似乎只在令牌器上起作用,就像短语“John Snow”一样。

代码语言:javascript
复制
{
  "query": {
      "match_phrase":{
      "dbName": "hn"
      }
  }
}

我的问题是:有没有更好的解决方案来处理包含模糊匹配的复杂查询,比如'%no%‘或'%hn_序列号%‘。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-16 11:06:01

您可以使用ngram 分词器每当它遇到指定字符列表中的一个字符时,它首先将文本分解为单词,然后发出指定长度的每个单词的N元语法。

添加一个包含索引数据、映射、搜索查询和结果的工作示例。

索引映射:

代码语言:javascript
复制
{
    "settings": {
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "tokenizer": "my_tokenizer"
                }
            },
            "tokenizer": {
                "my_tokenizer": {
                    "type": "ngram",
                    "min_gram": 2,
                    "max_gram": 10,
                    "token_chars": [
                        "letter",
                        "digit"
                    ]
                }
            }
        },
        "max_ngram_diff": 50
    },
    "mappings": {
        "properties": {
            "title": {
                "type": "text",
                "analyzer": "my_analyzer",
                "search_analyzer": "standard"
            }
        }
    }
}

分析API

代码语言:javascript
复制
POST/ _analyze

{
  "analyzer": "my_analyzer",
  "text": "John_Snow"
}

这些标记是:

代码语言:javascript
复制
{
    "tokens": [
        {
            "token": "Jo",
            "start_offset": 0,
            "end_offset": 2,
            "type": "word",
            "position": 0
        },
        {
            "token": "Joh",
            "start_offset": 0,
            "end_offset": 3,
            "type": "word",
            "position": 1
        },
        {
            "token": "John",
            "start_offset": 0,
            "end_offset": 4,
            "type": "word",
            "position": 2
        },
        {
            "token": "oh",
            "start_offset": 1,
            "end_offset": 3,
            "type": "word",
            "position": 3
        },
        {
            "token": "ohn",
            "start_offset": 1,
            "end_offset": 4,
            "type": "word",
            "position": 4
        },
        {
            "token": "hn",
            "start_offset": 2,
            "end_offset": 4,
            "type": "word",
            "position": 5
        },
        {
            "token": "Sn",
            "start_offset": 5,
            "end_offset": 7,
            "type": "word",
            "position": 6
        },
        {
            "token": "Sno",
            "start_offset": 5,
            "end_offset": 8,
            "type": "word",
            "position": 7
        },
        {
            "token": "Snow",
            "start_offset": 5,
            "end_offset": 9,
            "type": "word",
            "position": 8
        },
        {
            "token": "no",
            "start_offset": 6,
            "end_offset": 8,
            "type": "word",
            "position": 9
        },
        {
            "token": "now",
            "start_offset": 6,
            "end_offset": 9,
            "type": "word",
            "position": 10
        },
        {
            "token": "ow",
            "start_offset": 7,
            "end_offset": 9,
            "type": "word",
            "position": 11
        }
    ]
}

索引数据:

代码语言:javascript
复制
{
  "title":"John_Snow"
}

搜索查询:

代码语言:javascript
复制
{
    "query": {
        "match" : {
            "title" : "hn"
        }
    }
}

搜索结果:

代码语言:javascript
复制
"hits": [
            {
                "_index": "test",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.2876821,
                "_source": {
                    "title": "John_Snow"
                }
            }
        ]

另一个搜索查询

代码语言:javascript
复制
{
    "query": {
        "match" : {
            "title" : "ohr"
        }
    }
}

上述搜索查询未显示任何结果

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63912422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档