草庐IT

ElasticSearch中minimum_should_match理解

梦想东东 2024-05-10 原文

基于elasticsearch7.6.1 和 kibana7.6.1

本文通过案例进行讲解,希望读者耐心阅读【3.查询】中的内容。

1. 创建索引

PUT goods
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      }
    }
  }
}

 说明:

  1. 通常情况下,为了提升搜索的效果,ik_max_word和ik_smart两种分词器需要配合使用。
  2. 即构建索引时用ik_max_word,尽可能多的分词,而搜索时用ik_smart,尽可能提高匹配准度,让用户的搜索尽可能准确。

2. 通过_bulk批量导入数据

POST goods/_bulk
{"index":{"_id":1}}
{"title":"法国原瓶进口红酒"}
{"index":{"_id":2}}
{"title":"圣罗兰山茶色口红"}
{"index":{"_id":3}}
{"title":"康师傅红烧牛肉味方便面"}
{"index":{"_id":4}}
{"title":"康师傅芥末青柠味方便面"}
{"index":{"_id":5}}
{"title":"康师傅香辣牛肉味方便面"}
{"index":{"_id":6}}
{"title":"康师傅极致酷爽红茶"}
{"index":{"_id":7}}
{"title":"新西兰进口牛奶"}

3. 查询

# match查询
# 基于"进口" OR "红酒",进行召回。
GET goods/_search
{
  "query": {
    "match": {
      "title": "进口红酒"
    }
  }
}


GET goods/_search
{
  "query": {
    "match": {
      "title": "口红"
    }
  }
}


# 基于"康师傅" OR "红烧",进行召回。
GET goods/_search
{
  "query": {
    "match": {
      "title": {
        "query": "康师傅红烧"
      }
    }
  }
}

# 基于"康师傅" OR "红烧",进行召回,但是必须匹配两个词以上。
GET goods/_search
{
  "query": {
    "match": {
      "title": {
        "query": "康师傅红烧",
        "operator": "or",
        "minimum_should_match": 2
      }
    }
  }
}

# 基于"康师傅" AND "红烧",进行召回。
GET goods/_search
{
  "query": {
    "match": {
      "title": {
        "query": "康师傅红烧",
        "operator": "and"
      }
    }
  }
}

# 基于"康师傅" OR "红烧" OR "方便面",进行召回,但是必须匹配两个词以上。
GET goods/_search
{
  "query": {
    "match": {
      "title": {
        "query": "康师傅红烧方便面",
        "operator": "or",
        "minimum_should_match": 2
      }
    }
  }
}

# 3*75%=2.25,向下取整等于2。
# 基于"康师傅" OR "红烧" OR "方便面",进行召回,但是必须匹配两个词以上。
GET goods/_search
{
  "query": {
    "match": {
      "title": {
        "query": "康师傅红烧方便面",
        "operator": "or",
        "minimum_should_match": "75%"
      }
    }
  }
}

# 等价写法
GET goods/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "title": "康师傅"
          }
        },
        {
          "term": {
            "title": "红烧"
          }
        },
        {
          "term": {
            "title": "方便面"
          }
        }
      ],
      "minimum_should_match": 2
    }
  }
}


# 3*60%=1.8,向下取整等于1。
# 基于"康师傅" OR "红烧" OR "方便面",进行召回,但是必须匹配一个词以上。
GET goods/_search
{
  "query": {
    "match": {
      "title": {
        "query": "康师傅红烧方便面",
        "operator": "or",
        "minimum_should_match": "60%"
      }
    }
  }
}

# 等价写法
GET goods/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "title": "康师傅"
          }
        },
        {
          "term": {
            "title": "红烧"
          }
        },
        {
          "term": {
            "title": "方便面"
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}


# 如果clauses<=3,那么全部should条件都要满足,如果clauses>3,那么需要满足全部should条件的80%。
# 5*80%=4,向下取整等于4。
# 基于"康师傅" OR "红烧" OR "牛肉" OR "味" OR "方便面",进行召回,但是必须匹配4个词以上。
GET goods/_search
{
  "query": {
    "match": {
      "title": {
        "query": "康师傅红烧牛肉味方便面",
        "operator": "or",
        "minimum_should_match": "3<80%"
      }
    }
  }
}

# 等价写法
GET goods/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "title": "康师傅"
          }
        },
        {
          "term": {
            "title": "红烧"
          }
        },
        {
          "term": {
            "title": "牛肉"
          }
        },
        {
          "term": {
            "title": "味"
          }
        },
        {
          "term": {
            "title": "方便面"
          }
        }
      ],
      "minimum_should_match": 4
    }
  }
}


# 如果clauses<=3,那么全部should条件都要满足,如果clauses>3,那么需要满足全部should条件的80%。
# 基于"康师傅" OR "红烧" OR "方便面",进行召回,但是必须匹配3个词以上。
GET goods/_search
{
  "query": {
    "match": {
      "title": {
        "query": "康师傅红烧方便面",
        "operator": "or",
        "minimum_should_match": "3<80%"
      }
    }
  }
}

# 等价写法
GET goods/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "title": "康师傅"
          }
        },
        {
          "term": {
            "title": "红烧"
          }
        },
        {
          "term": {
            "title": "方便面"
          }
        }
      ],
      "minimum_should_match": 3
    }
  }
}

  说明:

  1. "minimum_should_match": "3<80%"含义:当should分支总数小于等于3时,则必须匹配所有的should分支,当should分支总数大于3时,则至少匹配80%的should分支,同时分支数向下取整。
  2. "minimum_should_match": "60%"含义:必须匹配should分支总数的60%,同时分支数向下取整。例如,总共有7个should分支,则7*0.6=4.2,向下取整得到4,即至少匹配4个should分支。

4. 补充,对比ik_max_word和ik_smart的分词效果

GET _analyze
{
  "analyzer": "ik_smart",
  "text": "进口红酒"
}


GET _analyze
{
  "analyzer": "ik_smart",
  "text": "康师傅红烧"
}


GET _analyze
{
  "analyzer": "ik_smart",
  "text": "康师傅红烧方便面"
}


GET _analyze
{
  "analyzer": "ik_smart",
  "text": "康师傅红烧牛肉味方便面"
}


GET _analyze
{
  "analyzer": "ik_max_word",
  "text": "新西兰进口牛奶"
}


GET _analyze
{
  "analyzer": "ik_max_word",
  "text": "康师傅红烧牛肉味方便面"
}


GET _analyze
{
  "analyzer": "ik_max_word",
  "text": "康师傅香辣牛肉味方便面"
}

有关ElasticSearch中minimum_should_match理解的更多相关文章

  1. c# - 线程和委托(delegate)——我不完全理解它们的关系 - 2

    我写了一段代码,看起来有点像这样:Threadt=newThread(()=>createSomething(dt,start,finish));t.Start();而且它有效(有时感觉就像有多个线程)。但我不使用任何委托(delegate)。没有委托(delegate)的踩踏是什么意思?如果需要委托(delegate)人——那么请告诉我与委托(delegate)人建立联系的方式和方式。 最佳答案 多线程非常复杂。您正在剪切和粘贴代码,甚至没有学习有关线程的最基本方面的任何知识——如何启动线程。将Web上的内容粘贴到UI中以修

  2. c# - LINQ to Entities Group By 表达式给出 'Anonymous type projection initializer should be simple name or member access expression' - 2

    我在这个表达式中遇到了上述错误:varaggregate=fromtinentities.TraceLinesjoinminentities.MethodNames.Where("it.NameLIKE@searchTerm",newObjectParameter("searchTerm",searchTerm))ont.MethodHashequalsm.MethodHashwhere(t.CallTypeId&(int)types)==t.CallTypeId&&t.UserSessionProcessId==m_Sessio

  3. c# - 如何在 C# 中进行列表理解(将列表转换为另一个列表的紧凑方式)? - 2

    在我的代码中,我经常有这样的序列:List<type1>list1=...;List<type2>list2=newList<type2>();foreach(type1l1inlist1){list2.Add(myTransformFunc(l1));}在Python中,我可以这样写list2=[myTransformFunc(l1)forl1inlist1]有没有一种用C#编写的紧凑方法? 最佳答案 varnewList=list.Select(x=>YourTransformFunc(

  4. c# - PropertyInfo 实例上的 SetValue 错误 "Object does not match target type"c# - 2

    在以前的项目中的不同地方使用了带有这段代码的Copy方法(处理具有相同命名属性但不派生自公共(public)基类或实现公共(public)接口(interface)的对象)。新的工作地点,新的代码库-现在即使在非常简单的示例中,它也会在SetValue处失败并显示“对象与目标类型不匹配”......并且它在上周工作......publicstaticvoidCopy(objectfromObj,objecttoObj){TypefromObjectType=fromObj.GetType();TypetoObjectType=toObj.GetType();foreach(System

  5. 再过半小时,你就能理解Kafka的基本原理了 - 2

    kafka总结一.定义二.基础架构及术语三.工作流程分析3.1发送数据3.2保存数据3.2.1partition结构3.2.2message结构3.2.3存储策略3.2.4消费数据一.定义Kafka是一种高吞吐量的分布式发布订阅消息系统,可以处理消费者规模的网站中的所有动作流数据,具有高性能,持久化,多副本备份,横向扩展能力等。二.基础架构及术语Producer:生产者,消息的生产者,消息的入口Kafkacluster:Broker:brocker是kaf

  6. JSD-2204-Elasticsearch-SpringData-酷鲨商城概述-Day07 - 2

    1.操作Elasticsearch项目csmall-finish项目中node文件夹下共享了ES文档,命令都在里面,可以测试所有的代码都在"ES文档"中, 笔记略下面我们要学习使用java代码来操作ES2.SpringBoot操作Elasticsearch2.1SpringData简介原生状态下,我们使用JDBC连接数据库,因为代码过于繁琐,所以改为使用Mybatis框架在ES的原生状态下,我们java代码需要使用socket访问ES,但是也是过于繁琐,我们可以使用SpringData框架简化SpringData是Spring提供的一套连接各种第三方数据源的框架集我们需要使用的

  7. 基于Docker和ES存储的Skywalking部署 - 2

    文章目录一、ES的Docker部署二、Kibana:ES可视化部署三、服务端skywalking-oap部署四、可视化skywalking-ui部署五、Java应用引入agent5.1agent下载与配置5.2jar包启动带agent命令5.3在skywalking-ui查看监测内容一、ES的Docker部署#下载es镜像dockerpullelasticsearch:6.8.12#启动es镜像dockerrun--restart=always-p9200:9200-p9300:9300-e"discovery.type=single-node"-eES_JAV

  8. c# - 理解调度队列 - 2

    我想我需要一些帮助来理解DispatcherQueue。当新工作到达时,它会被添加到调度程序队列的开头,而当Dispatcher想要处理工作项时,它会从开头被删除。更一般地说:如果有工作,它将以FIFO方式存储在队列中,并在没有剩余工作时进行处理。MSDN文档here是指loop和frame:Dispatcher在循环中处理工作项队列。循环称为帧。但是在这种情况下循环在哪里?对我来说,循环是指迭代某些东西,当它到达终点时,它会重新开始。frame的概念是什么?根据MSDN文档,一个框架是队列中工作项目的一部分?如果是这样,应该如何使用静态方法Disptatcher.PushFrame(

  9. c# - C# VS2010 项目中的 "PDB does not match image"错误 - 2

    我在我的代码库中使用库已有一段时间了,我想直接调试到库级别。为此,我下载了源代码并将该项目作为现有项目包含到我的C#解决方案中。然后我让我的其他项目引用该项目而不是下载的.DLL。在引用项目而不是DLL后,我通过调试器运行我的解决方案并尝试进入一个函数调用,该函数调用本应调用外部项目,但它直接越过它。调试时,我打开“模块”窗口,看到DLL的符号状态显示为“PDB与图像不匹配”,这可能是无法调试此项目的原因。我的问题很简单,如果我的项目直接引用.csproj文件作为引用,为什么PDB与图像不匹配?对于要运行的版本,绝不应该有任何歧义。 最佳答案

  10. c# - 如何将单个 .NET 类型映射到 ElasticSearch/NEST 中的多个嵌套对象类型? - 2

    我正在使用NEST库与ElasticSearch交互,并且我正在尝试找出一种基于非类型数据构建索引类型/嵌套对象的方法。该类型具有以下基本结构。publicclassEntity:DynamicObject{publicstringId{get;set;}//abunchofothersimplepropertiespublicoverrideIEnumerable<string>GetDynamicMemberNames(){returnData.Select(x=>x.Name);}publicoverrideboolTryGetMember(GetMemberB

随机推荐

  1. c# - 当我在 if 子句中放置一个关闭的 div 标签时,Razor 会提示 - 2

    我正在尝试使用Razor模板来执行此操作:@if(isNew){<divclass="new">}...@if(isNew){</div>}错误是:cannotresolvethesymbol'div'Razor不喜欢IF子句中的结束div标记,我怎样才能让它工作?我必须使用转义吗? 最佳答案 Razor不喜欢像这样拆分开始/结束标记,因为它无法正确解析HTML,因此您必须将它们转义为纯文本:@if(isNew){@:<divclass="new">

  2. c# - LINQ 按字母顺序排列,后跟空字符串 - 2

    我有一个字符串集合:"","c","a","b".我想使用LINQsorderby以便顺序按字母顺序排列,但最后是空字符串。所以在上面的例子中,顺序是:"a","b","c","" 最佳答案 你可以使用类似的东西:varresult=new[]{"a","c","","b","d",}.OrderBy(string.IsNull

  3. c# - 从 linq to sql 中的子查询中选择前 1 个结果 - 2

    下面是我的sql查询selectenq_Id,enq_FromName,enq_EmailId,enq_Phone,enq_Subject,enq_Message,enq_EnquiryBy,enq_Mode,enq_Date,ProductId,(selecttop1image_namefromtblProductImageasiwherei.product_id=p.product_Id)asimageName,p.product_Name,p.product_codefromtblEnquiryaseinnerjointblProductaspONe.ProductId=p.pr

  4. c# - 在 asp.net gridview 中禁用文本换行 - 2

    输出是这样的:MyNameIsJohnSmithAndImaperson我想要的是只显示一行MyNameIsJohnSmithAndImaperson我的Aspxgridview代码是:<asp:GridViewID="GridView1"runat="server"BackColor="LightGoldenrodYellow"BorderColor="Tan"BorderWidth="1px"CellPadding="5"Font-Names="Calibri"Fo

  5. c# - XML字符串反序列化为c#对象 - 2

    我收到这样的xml文件。<radio><channelid="Opus"><display-name>Opus</display-name><iconsrc=""/></channel><channelid="Klasika"><display-name>Klasika</display-name><iconsrc=""/></channel><channelid="LR"

  6. c# - C#中如何从数组中获取随机值 - 2

    这个问题在这里已经有了答案:关闭9年前。PossibleDuplicate:Accessrandomiteminlist我有一个包含数字的数组,我想从这个数组中获取随机元素。例如:{0,1,4,6,8,2}。我想选择6并将这个数字放在另一个数组中,新数组的值为{6,....}。我使用random.next(0,array.length),但这给出了长度的随机数,我需要随机数组数。for(inti=0;i<caminohormiga.Length;i++){if(caminohormiga[i]==0){continue;}for(intj=0;j<caminohormiga

  7. c# - 获取 Dictionary 中包含值 x 的所有键 - 2

    我有这个:Dictionary<integer,string>dict=newDictionary<integer,string>();我想选择字典中包含值abc的所有项目。是否有内置函数可以让我轻松地做到这一点? 最佳答案 好吧,使用LINQ合理简单:varmatches=dict.Where(pair=>pair.Value=="abc").Select(pair=>pair.Key);请注意,这不会有任何效率-它是一个O(N)操作,因为它需要检查每个条目。如果您需要经常这样做

  8. C# 不可变整数 - 2

    在Java中,字符串是不可变的。如果我们有一个字符串并对其进行更改,我们将获得由同一变量引用的新字符串:Stringstr="abc";str+="def";//nowstrreferstoanotherpieceintheheapcontaining"abcdef"//while"abc"isstillsomewhereintheheapuntiltakenbyGCIt'sbeensaidint和double在C#中是不可变的。这是否意味着当我们拥有int并稍后更改它时,我们会得到同一个变量“指向”的新int?同

  9. c# - Observable.Timer() : How to avoid timer drift? - 2

    在C#(.NET4.0)应用程序中,我使用ReactiveExtensions(2.0.20823.0)生成时间边界以将事件分组为聚合值。为了简化对生成的数据库的查询,这些边界需要在整个小时(或下例中的秒)对齐。使用Observable.Timer():vartime=DefaultScheduler.Instance;varstart=newDateTimeOffset(time.Now.DateTime,time.Now.Offset);varspan=TimeSpan.FromSeconds(1);start-=TimeSpan.FromTicks(start.Ticks%100

  10. c# - 读取大 TXT 文件,内存不足异常 - 2

    我想阅读大TXT文件,大小为500MB,首先我使用varfile=newStreamReader(_filePath).ReadToEnd();varlines=file.Split(new[]{'\n'});但它抛出内存异常,然后我尝试逐行读取,但在读取大约150万行后再次抛出内存异常using(StreamReaderr=newStreamReader(_filePath)){while((line=r.ReadLine())!=null)_lines.Add(line);}或者我用过foreach(varlinFile.ReadLines(_filePath)){