Elasticsearch:查找子字符串匹配

     2023-03-05     305

关键词:

【中文标题】Elasticsearch:查找子字符串匹配【英文标题】:Elasticsearch: Find substring match 【发布时间】:2014-06-08 06:15:30 【问题描述】:

我想同时执行完全单词匹配和部分单词/子字符串匹配。例如,如果我搜索“男士剃须刀”,那么我应该能够在结果中找到“男士剃须刀”。但如果我搜索“en's shaver”,那么我也应该能够在结果中找到“men's shaver”。 我使用以下设置和映射:

索引设置:

PUT /my_index

    "settings": 
        "number_of_shards": 1, 
        "analysis": 
            "filter": 
                "autocomplete_filter":  
                    "type":     "edge_ngram",
                    "min_gram": 1,
                    "max_gram": 20
                
            ,
            "analyzer": 
                "autocomplete": 
                    "type":      "custom",
                    "tokenizer": "standard",
                    "filter": [
                        "lowercase",
                        "autocomplete_filter" 
                    ]
                
            
        
    

映射:

PUT /my_index/my_type/_mapping

    "my_type": 
        "properties": 
            "name": 
                "type":            "string",
                "index_analyzer":  "autocomplete", 
                "search_analyzer": "standard" 
            
        
    

插入记录:

POST /my_index/my_type/_bulk
 "index":  "_id": 1            
 "name": "men's shaver" 
 "index":  "_id": 2            
 "name": "women's shaver" 

查询:

1.按精确词组匹配搜索 --> "men's"

POST /my_index/my_type/_search

    "query": 
        "match": 
            "name": "men's"
        
    

以上查询在返回结果中返回“男士剃须刀”。

2。按部分单词匹配搜索 --> "en's"

POST /my_index/my_type/_search

    "query": 
        "match": 
            "name": "en's"
        
    

以上查询不返回任何内容。

我也尝试过以下查询

POST /my_index/my_type/_search

    "query": 
        "wildcard": 
           "name": 
              "value": "%en's%"
           
        
    

仍然没有得到任何东西。 我认为这是因为 Index 上的“edge_ngram”类型过滤器无法找到“部分单词/sbustring 匹配”。 我也尝试了“n-gram”类型的过滤器,但它大大减慢了搜索速度。

请建议我如何使用相同的索引设置同时实现精确词组匹配和部分词组匹配。

【问题讨论】:

【参考方案1】:

要搜索部分字段匹配和完全匹配,如果您将字段定义为“未分析”或关键字(而不是文本),则效果会更好,然后使用通配符查询

See also this.

要使用通配符查询,请在要搜索的字符串的两端附加 *:

POST /my_index/my_type/_search

"query": 
    "wildcard": 
       "name": 
          "value": "*en's*"
       
    


要与不区分大小写一起使用,请使用带有小写过滤器和关键字标记器的自定义分析器。

自定义分析器:

"custom_analyzer": 
    "tokenizer": "keyword",
    "filter": ["lowercase"]

将搜索字符串设为小写

如果搜索字符串为 AsD:将其更改为 *asd*

【讨论】:

谢谢。我现在可以搜索了。 引用 ElasticSearch 的文档:“警告:允许在单词开头使用通配符(例如“*ing”)特别繁重,因为索引中的所有术语都需要检查”@987654322 @ 感谢您的提醒! @david_p @david_p 的链接已损坏,但正如他所说,ElasticSearch 建议“避免使用以通配符开头的模式(例如,*foo 或作为正则表达式的 .*foo)” . elastic.co/guide/en/elasticsearch/guide/current/… 它不适用于不区分大小写的情况。我们如何使用它来区分大小写?【参考方案2】:

@BlackPOP 给出的答案会起作用,但它使用通配符方法,这不是首选,因为它存在性能问题,如果滥用会在 Elastic 集群中产生巨大的多米诺骨牌效应(性能问题)。

我在部分搜索/自动完成方面写了详细的blog,涵盖了截至今天(2020 年 12 月)在 Elasticsearch 中可用的最新选项,并考虑了性能。更多权衡信息请参考this解答。

恕我直言,更好的方法是根据用例使用自定义的n-gram tokenizer,它已经具有搜索词所需的令牌,因此它会更快,虽然它会有更大的索引大小,但你的大小是不是那么昂贵,并且通过更多地控制您希望子字符串搜索的工作方式,速度会更好。

如果您在分词器设置中定义最小和最大克数时保守,也可以控制大小。

【讨论】:

【参考方案3】:

通过搜索任何字符串或子字符串使用:

query: 
    or: [
      match_phrase_prefix: 
            name: str
     
    , 
        match_phrase_prefix: 
            surname: str
        
    ]

使用 Elastic Search 进行愉快的编码......

【讨论】:

他不是在寻找匹配的前缀。

MySQL 查找子字符串匹配并按匹配全字分组

】MySQL查找子字符串匹配并按匹配全字分组【英文标题】:MySQLFindingSubstringMatchesandGroupbyMatchFullWord【发布时间】:2018-08-0619:59:38【问题描述】:使用MySQL时,我找不到该表达式的正确术语组合。在我的语句中使用PHP用户输入变量... 查看详情

在 .NET 中查找子字符串匹配的结尾

】在.NET中查找子字符串匹配的结尾【英文标题】:Findingtheendofasubstringmatchin.NET【发布时间】:2008-10-0811:56:30【问题描述】:我正在尝试查找与特定文化下的另一个字符串匹配的字符串中的子字符串的索引(由System.CultureInfo提供... 查看详情

查找重叠子串的多个匹配项

...间】:2017-05-0106:53:57【问题描述】:我正在尝试查找重叠字符串的多个匹配项,并带有单词边界。一旦找到一个子串,它就不会被考虑用于未来的匹配,即下一次搜索将在该子串的结尾之后开始。例如,我需要此字符串的这些匹... 查看详情

查找其键与子字符串匹配的字典项

】查找其键与子字符串匹配的字典项【英文标题】:Finddictionaryitemswhosekeymatchesasubstring【发布时间】:2012-05-1602:08:59【问题描述】:我有一个像这样构造的大字典:programs[\'NewYork\']=\'somevalues...\'programs[\'PortAuthorityofNewYork\']=\'someval... 查看详情

查找大型数据集中子字符串的所有匹配项的(行、列)位置

】查找大型数据集中子字符串的所有匹配项的(行、列)位置【英文标题】:Findthe(row,column)locationsofallmatchestoasubstringinlargedataset【发布时间】:2018-07-2023:33:19【问题描述】:在大型数据集中查找包含子字符串“en”的所有匹配项... 查看详情

跨多个候选项查找多个子字符串的最佳匹配

】跨多个候选项查找多个子字符串的最佳匹配【英文标题】:Findbestmatchformultiplesubstringsacrossmultiplecandidates【发布时间】:2020-04-1210:36:38【问题描述】:我有以下示例数据:targets<-c("der","das")candidates<-c("sdassder","sderf","fongs")所... 查看详情

查找所有匹配的子字符串,而不仅仅是“最扩展”的子字符串

】查找所有匹配的子字符串,而不仅仅是“最扩展”的子字符串【英文标题】:Findingallofthematchingsubstrings,notonlythe"mostextended"one【发布时间】:2012-06-2900:19:26【问题描述】:代码Strings="yzaaabccz";Patternp=Pattern.compile("(a)+(b)+(c*)... 查看详情

通过Python中的正则表达式优化在两个列表之间查找匹配子字符串

...通过Python中的正则表达式优化在两个列表之间查找匹配子字符串【英文标题】:OptimizingfindingmatchingsubstringbetweenthetwolistsbyregexinPython【发布时间】:2019-08-0818:04:24【问题描述】:这是我在包含“短语”的列表中查找子字符串的方... 查看详情

搜索元组列表以查找匹配子字符串的算法方法?

】搜索元组列表以查找匹配子字符串的算法方法?【英文标题】:Algorithmicwaytosearchalistoftuplesforamatchingsubstring?【发布时间】:2021-03-0806:25:47【问题描述】:我有一个元组列表,大约有100k个条目。每个元组由一个id和一个字符串组... 查看详情

kmp模式匹配,查找子字符串(代码片段)

代码解析voidcal_next(char*ptr,int*next,intplen)next[0]=-1;intk=-1;for(inti=1;i<=plen-1;i++)while(k>-1&&ptr[k+1]!=ptr[i])k=next[k];if(ptr[k+1]==ptr[i])k=k+1;next[i]=k;一.voidcal_next(c 查看详情

查找和替换文件中与另一个文件中的字符串匹配的子字符串

】查找和替换文件中与另一个文件中的字符串匹配的子字符串【英文标题】:findandreplacesubstringsinafilewhichmatchstringsinanotherfile【发布时间】:2020-03-2512:03:21【问题描述】:我有两个txt文件:File1是一个有9列的tsv。以下是它的第一... 查看详情

查找所有正则表达式匹配的索引?

...【问题描述】:我正在解析其中可能包含任意数量的引号字符串的字符串(我正在解析代码,并试图避免PLY)。我想知道是否引用了子字符串,并且我有子字符串索引。我最初的想法是使用re查找所有匹配项,然后找出它们所代... 查看详情

子字符查找kmp算法-子串自匹配索引表

publicstaticint[]kmpTable(char[]seq){int[]tbl=newint[seq.length];tbl[0]=1;for(inti=1;i<seq.length;i++){//子串最开始intj=tbl[i-1];//从已经算出的索引开始l1:for(;j<=i;j++){for(intk=0;j+k<=i;k++){if(seq[j+k]==s 查看详情

SOLR 中的子字符串匹配

】SOLR中的子字符串匹配【英文标题】:SubstringmatcheswithinSOLR【发布时间】:2011-03-0612:40:53【问题描述】:我似乎无法弄清楚如何使用SOLR查找子字符串匹配项,我已经根据前缀找出匹配项,因此我可以让ham匹配汉堡包。如何搜索... 查看详情

使用后缀树进行近似子串匹配

...述】:本文讨论了利用suffixtree来缩短匹配时间的近似子字符串匹配技术。每个答案都针对不同的算法。近似子字符串匹配尝试在字符串T中查找子字符串(模式)P,最多允许k不匹配。要了解如何创建后缀树,请单击here。但是,... 查看详情

40python正则表达式match方法匹配字符串使用search函数在一个字符串中查找子字

第一课:使用match方法匹配字符串#正则表达式:使用match方法匹配字符串‘‘‘正则表达式:是用来处理文本的,将一组类似的字符串进行抽象,形成的文本模式字符串windowsdir*.txtfile1.txtfile2.txtabc.txttest.doca-file1.txt-blinux/macls主要... 查看详情

查找子字符串在父串中的位置

参考技术A经常会遇到在一串字符串中查找匹配的子字符串位置,特记录下NSString*string1=@"Thisishelloworld";NSString*string2=@"is";NSRangerange=[string1rangeOfString:string2];NSLog(@"length:%d..location:%d.",range.length,range.location);总结... 查看详情

我们如何使用动态编程解决子字符串匹配检查

】我们如何使用动态编程解决子字符串匹配检查【英文标题】:HowcanwesolvesubstringmatchingcheckusingDynamicProgramming【发布时间】:2014-11-1918:39:00【问题描述】:我学习了使用动态编程查找最长公共子串的程序。我们也可以使用动态规... 查看详情