Elasticsearch实战-Match/Match_phrase/term/filter 及Must should 组合并列使用

文章目录

  • Elasticsearch实战-Match/Match_phrase/term/filter 及Must should 组合并列使用
    • 1.Match/Match_phrase/term
      • 1.1 准备数据
      • 1.2 Match 用法
      • 1.3 Match_phrase 用法
      • 1.4 term 用法
    • 2.Must / Should 组合并列使用
      • 2.1 A & B & (C || D) 错误写法
      • 2.2 A & B & (C || D) 正确写法 Should放入Must内层中
      • 2.3 A & B & (C || D) 使用 Filter 实现

1.Match/Match_phrase/term

  1. math:将词分割开来,匹配倒排索引,查找包含任意分割的词的字段。根据你的分词去匹配
    比如 你用的标准分词, 湖北省(湖/北/省) 如果用的IK_smart 分词 就是用的 湖北省(湖北省/湖北省) 如果用的IK_max_word细粒度分词就是 湖北省(湖北省/湖北/省)
  2. term:不分割词,直接匹配倒排索引。 传入的文本原封不动地(不分词)拿去查询。你输入的是湖北省, 如果结果中湖北省武汉市 是查不出来的
  3. match_phrase: 将词分割开来,匹配倒排索引,查找这个短语。 比如湖北省武汉市, 结果中有 湖北省武汉市洪山区, 湖北省武汉市东湖隧道, 这些都能查出来,因为 结果中包含了 湖北省武汉市 整个短语
  4. filter和Query有什么区别 , filter过滤的性能好于查询的性能, 为什么 ? 因为 filter 过滤不计算得分,但是查询计算得分, 而且过滤可以使用缓存,但是查询不会使用缓冲
1.1 准备数据

empId:员工id, salary 表示薪资, deptName:部门, address:地址

POST /testboost/_bulk
{"index":{"_id": 1}}
{"empId" : "111","name" : "员工1","age" : 20,"sex" : "男","mobile" : "19000001111","salary":1333,"deptName" : "技术部","address" : "湖北省武汉市洪山区光谷大厦"}
{"index":{"_id": 2}}
{"empId" : "222","name" : "员工2","age" : 25,"sex" : "男","mobile" : "19000002222","salary":15963,"deptName" : "销售部","address" : "湖北省武汉市江汉路"}
{"index":{"_id": 3}}
{ "empId" : "333","name" : "员工3","age" : 30,"sex" : "男","mobile" : "19000003333","salary":20000,"deptName" : "技术部","address" : "湖北省武汉市经济开发区"}
{"index":{"_id": 4}}
{"empId" : "444","name" : "员工4","age" : 20,"sex" : "女","mobile" : "19000004444","salary":5600,"deptName" : "销售部","address" : "湖北省武汉市沌口开发区"}
{"index":{"_id": 5}}
{ "empId" : "555","name" : "员工5","age" : 20,"sex" : "男","mobile" : "19000005555","salary":9665,"deptName" : "测试部","address" : "湖北省武汉市东湖隧道"}
{"index":{"_id": 6}}
{"empId" : "666","name" : "员工6","age" : 30,"sex" : "女","mobile" : "19000006666","salary":30000,"deptName" : "技术部","address" : "湖北省武汉市江汉路"}
{"index":{"_id": 7}}
{"empId" : "777","name" : "员工7","age" : 60,"sex" : "女","mobile" : "19000007777","salary":52130,"deptName" : "测试部","address" : "湖北省黄冈市边城区"}
{"index":{"_id": 8}}
{"empId" : "888","name" : "员工8","age" : 19,"sex" : "女","mobile" : "19000008888","salary":60000,"deptName" : "技术部","address" : "湖北省武汉市江汉大学"}
{"index":{"_id": 9}}
{"empId" : "999","name" : "员工9","age" : 40,"sex" : "男","mobile" : "19000009999","salary":23000,"deptName" : "销售部","address" : "河南省郑州市郑州大学"}
{"index":{"_id": 10}}
{"empId" : "101010","name" : "张湖北","age" : 35,"sex" : "男","mobile" : "19000001010","salary":18000,"deptName" : "测试部","address" : "湖北省武汉市东湖高新"}
{"index":{"_id": 11}}
{"empId" : "111111","name" : "王河南","age" : 61,"sex" : "男","mobile" : "19000001011","salary":10000,"deptName" : "销售部","address" : "河南省开封市河南大学"}
{"index":{"_id": 12}}
{"empId" : "121212","name" : "张大学","age" : 26,"sex" : "女","mobile" : "19000001012","salary":1321,"deptName" : "测试部","address" : "河南省开封市河南大学"}
{"index":{"_id": 13}}
{"empId" : "131313","name" : "李江汉","age" : 36,"sex" : "男","mobile" : "19000001013","salary":1125,"deptName" : "销售部","address" : "河南省郑州市二七区"}
{"index":{"_id": 14}}
{"empId" : "141414","name" : "王技术","age" : 45,"sex" : "女","mobile" : "19000001014","salary":6222,"deptName" : "测试部","address" : "河南省郑州市金水区"}
{"index":{"_id": 15}}
{"empId" : "151515","name" : "张测试","age" : 18,"sex" : "男","mobile" : "19000001015","salary":20000,"deptName" : "技术部","address" : "河南省郑州高新开发区"}
1.2 Match 用法

Match就是匹配, 切分关键字,输入 湖北省, 切分 湖/北/省

//查询地址 中包含湖北省
get /testboost/_search
{"query":{"match": {"address": "湖北省"}}
}

所以查询结果 把 河南 “省” 带省的也查询出来了

1.3 Match_phrase 用法

如果我想查 “湖北省” 不要 查 省的 结果中不带 河南省的 那么就要 用到 match_phrase 把查询条件当作 短语来查找了

//把湖北省当作 短语不分词 模糊查询 ,比如 湖北省xxx ,湖北省 都查出来
get /testboost/_search
{"query":{"match_phrase": {"address": "湖北省"}}
}

可以看到 查询结果都是 湖北的 ,是没 河南省信息的, 包含湖北省的才会查出来

1.4 term 用法

按照官方文档 term应该是不分词就查询的, 所以我们 直接把 整个地址 当作查询 就行

//term不分词, 直接查 整个地址是 湖北省武汉市经济开发区 的,结果查不出来,为什么?
get /testboost/_search
{"query":{"term": {"address": "湖北省武汉市经济开发区"}}
}

可以看到 是没有数据的,为什么 , 明明我的数据 中有 地址是 “湖北省武汉市经济开发区” 的数据的?

!!! 使用term去查询,其实是拿查询条件和被分词的索引关键字一一匹配,
我们的address是个text类型的字段,被分词器分词了,并且 湖北省武汉市经济技术开发区 就被 分成了 一个个字的 分词 , 需要你在构建索引的时候 插入mapping 指定 ,确保字段是no analyzed的。 建索引的时候要注意

既然这样, term根据 索引去查询, 我的索引又是单个字的, 我试试单个字查询有没有问题, 搜"区" 是没问题的

2.Must / Should 组合并列使用

2.1 A & B & (C || D) 错误写法

我想搜 地址必须湖北省,性别男 并且 部门是技术部 或者 销售部 操作 就是 A && B && ( C || D) 这种查询应该如何查
地址 must操作, 技术部或者测试部 should操作
注意 此时 Must 条件和 Should 是同等级别的 ,

#  执行错误示范 这个是  address=湖北省 and sex=男 or 部门=技术部/销售部, 会把 测试部的人拉出来, 说明should 不生效
# 此时 must 和 should 是同等级别的
get /testboost/_search
{"query":{"bool": {"must": [{"match_phrase": {"address": "湖北省"}},{"match": {"sex": "男"}}],"should": [{"match_phrase": {"deptName": "销售部"}},{"match_phrase": {"deptName": "技术部"}}]}}
}

错误的查询结果 , 为什么should 不生效呢? 为什么把 测试部们查了出来, 明明should 写了 只查满足 部门=销售部或技术部的,但是结果把测试部查了出来

所以 应该怎么写?结论就是 应该把 should 放到 Must中 试一试

2.2 A & B & (C || D) 正确写法 Should放入Must内层中

湖北省 && 男生 && (技术部 || 销售部) ? 如何实现

get /testboost/_search
{"query":{"bool": {"must": [{"match_phrase": {"address": "湖北省"}},      {"match": {"sex": "男"}},//注意 查询 should 是在must 内部写的,should要用 bool结构{"bool": {"should": [{"match_phrase": {"deptName": "技术部"}},{"match_phrase": {"deptName": "销售部"}}]}}]}
}
}

看下结果, 只有 湖北省且 男且 部门是销售部或技术部 的才查出来, 结果正确
注意 此时 should是放在 must 内层的, 和 湖北省, 男 , 是同等级别 ,这就是区别

结果正常

2.3 A & B & (C || D) 使用 Filter 实现

湖北省 && 男生 && (技术部 || 销售部) ?filter如何实现 其实就是 先查出来 湖北省 && 男生的 所有部门的信息
然后过滤 filter 过滤出来 是技术部或者销售部的 信息

# 湖北省 && 男生 && (技术部 || 销售部) filter 先用 must 查 湖北省and男 结果,然后过滤 技术部或者销售部的人
get /testboost/_search
{"query":{"bool": {"must": [{"match_phrase": {"address": "湖北省"}},{"match_phrase": {"sex": "男"}}],"filter": [{"bool": {"should": [{"match_phrase": {"deptName": "技术部"}},{"match_phrase": {"deptName": "销售部"}}]}}]}
}
}

看下结果, 只有 湖北省且 男且 部门是销售部或技术部 的才查出来,通过filter 也是能够得出正确结果的

结果正常


至此 我们Match Match_phrase 及Term 使用和区别 也讲了, Must及should 组合并列使用的 如何正确查出结果 也讲了, 下一篇 我们将 如何排名

Elasticsearch实战(五)---高级搜索 Match/Match_phrase/Term/Must/should 组合使用相关推荐

  1. elasticsearch系列五:搜索详解(查询建议介绍、Suggester 介绍)

    一.查询建议介绍 1. 查询建议是什么? 查询建议,为用户提供良好的使用体验.主要包括: 拼写检查: 自动建议查询词(自动补全) 拼写检查如图: 自动建议查询词(自动补全): 2. ES中查询建议的A ...

  2. Elasticsearch实战(五)-倒排索引与分词

    1 倒排索引 1.1 书的目录和索引 正排索引即目录页,根据页码去找内容 倒排索引即索引页,根据关键词去找对应页码 1.2 搜索引擎 正排索引 文档Id =>文档内容.单词的关联关系 倒排索引 ...

  3. Elasticsearch - HTTP操作索引,文档,映射;高级搜索(五)

    阅读本文前可先参考 https://blog.csdn.net/MinggeQingchun/article/details/126618387 https://blog.csdn.net/Mingg ...

  4. elasticsearch高级搜索功能多维度分享

    目录 一.业务搜索核心功能 二.高级搜索匹配功能 三.搜索排序功能 elasticsearch高级搜索功能多维度分享,这也是实战的比较之路,此次我们全面分享常用的业务情景,全覆盖功能分享,让大家有一览 ...

  5. elasticsearch实战三部曲之三:搜索操作

    elasticsearch实战三部曲之三:搜索操作 2019年01月13日 21:35:18 博陵精骑 阅读数:1367 标签: elasticsearch 更多 个人分类: elasticsearc ...

  6. Elasticsearch教程(28) text和keyword区别 term和match区别 ik中文分词器使用

    text和keyword区别 term和match区别 ik中文分词器使用 一.前言 二.之前相关的博客 三.造点测试数据 1. 创建一个index 2. 插入测试数据 四.做一份试卷 第1题:tit ...

  7. elasticsearch 查询(match和term)

    elasticsearch 查询(match和term) es中的查询请求有两种方式,一种是简易版的查询,另外一种是使用JSON完整的请求体,叫做结构化查询(DSL). 由于DSL查询更为直观也更为简 ...

  8. Elasticsearch项目实战,商品搜索功能设计与实现!

    推荐大家去看原文博主的文章,条理清晰阅读方便,转载是为了方便以后个人查阅 https://juejin.im/post/5e94587f51882573be11cb83?utm_source=gold ...

  9. Elasticsearch 实战 - 第四讲:ES 高级查询

    Elasticsearch 实战 - 第四讲:ES 高级查询 Elasticsearch 实战系列文章: 一.高级查询 1.简介 2.结果排序 3.分页查询 4.检索查询 5.关键字查询 6.高亮显示 ...

最新文章

  1. 邮箱@topgrid.cn是什么网站_典 藏 网 站 !
  2. 23种设计模式(11):责任链模式
  3. learning hdmi edid protocol
  4. 官网,一套代码如何运行多端?
  5. 数字转化成时分秒(二)
  6. python程序打完后怎么保存_如何保存要在之后使用的值应用程序执行()在python中退出?...
  7. ctrl+alt+T出来的终端窗口非常小
  8. Spring框架声明式事务管理
  9. hadoop mapreduce开发实践之本地文件分发by streaming
  10. js html 加背景图片,利用js实现随机背景显示,每次访问背景图都不一样
  11. html5在线拍照 源码,html5拍照功能实现代码(htm5上传文件)
  12. P2P风控措施和风控流程
  13. 总结:python paramiko winrm
  14. 超好用的两款作图工具,用起来~~~
  15. Python输出函数print()总结(python print())
  16. 史上最全SpringBoot教程,从零开始带你深入♂学习(四)——web开发
  17. 【学习】关于网站中图片的各类交互
  18. 3D数据---未来数字世界的物质基础
  19. spring boot 资料整合
  20. 【缅怀】缅怀汶川地震记

热门文章

  1. 如何进行织梦产品详情页面仿制
  2. Biorhythms(生物周期)
  3. 百分百全开源的ERP项目,太赞了
  4. ES6转码(编译)工具——Babel转码器、Traceur转码器
  5. 推进“五社联动” 关爱“一小一老”——反诈知识宣传活动
  6. BSCI官网如何下载审核图片记录?
  7. Java实现Excel文件读写
  8. 超链接target属性的取值和作用?
  9. DevExpress TreeList实现TreeView普通样式
  10. Delphi中MDI窗体调用MDI子窗体Delphi中MDI窗体调用MDI子窗体,怎么调用