转摘自:https://elasticstack.blog.csdn.net/article/details/114261636

  1. Elasticsearch 是一个应用非常广泛的搜索引擎。它可以对文字进行分词,从而实现全文搜索。在实际的使用中,我们会发现有一些文字中包含一些表情符号,比如笑脸,动物等等,那么我们该如何对这些表情符号来进行搜索呢?
  2. => , light skin tone, skin tone, type 12
  3. => , medium-light skin tone, skin tone, type 3
  4. => , medium skin tone, skin tone, type 4
  5. => , medium-dark skin tone, skin tone, type 5
  6. => , dark skin tone, skin tone, type 6
  7. => ♪, eighth, music, note
  8. => ♭, bemolle, flat, music, note
  9. => ♯, dièse, diesis, music, note, sharp
  10. => , face, grin, grinning face
  11. => , face, grinning face with big eyes, mouth, open, smile
  12. => , eye, face, grinning face with smiling eyes, mouth, open, smile
  13. => , beaming face with smiling eyes, eye, face, grin, smile
  14. => , face, grinning squinting face, laugh, mouth, satisfied, smile
  15. => , cold, face, grinning face with sweat, open, smile, sweat
  16. => , face, floor, laugh, rofl, rolling, rolling on the floor laughing, rotfl
  17. => , face, face with tears of joy, joy, laugh, tear
  18. => , face, slightly smiling face, smile
  19. => , face, upside-down
  20. => , face, wink, winking face
  21. => , tiger
  22. => , leopard
  23. => , face, horse
  24. => , equestrian, horse, racehorse, racing
  25. => , face, unicorn
  26. => , stripe, zebra
  27. => , deer
  28. 在上面,我们可以看到各种各样的 emoji 符号。比如我们想搜索 grin,那么它就把含有 emoji 符号的文档也找出来。在今天的文章中,我们来展示如何实现对 emoji 符号的进行搜索。
  29. 安装
  30. 如果你还没有对 Elasticsearch Kibana 进行安装的话,请参阅之前的文章 Elastic:菜鸟上手指南” 进行安装。 另外,我们必须安装 ICU analyzer。关于 ICU analyzer 的安装,请参阅之前的文章 ElasticsearchICU 分词器介绍”。我们在 Elasticsearch 的安装根目录中,打入如下的命令:
  31. ./bin/elasticsearch-plugin install analysis-icu
  32. 等安装好后,我们需要重新启动 Elasticsearch 让它起作用。运行:
  33. ./bin/elasticsearch-plugin list
  34. 上面的命令显示:
  35. $ ./bin/elasticsearch-plugin install analysis-icu
  36. -> Installing analysis-icu
  37. -> Downloading analysis-icu from elastic
  38. [=================================================] 100%
  39. -> Installed analysis-icu
  40. $ ./bin/elasticsearch-plugin list
  41. analysis-icu
  42. 安装完 ICU analyzer 后,我们必须重新启动 Elasticsearch
  43. 搜索 emoji 符号
  44. 我们先做一个简单的实验:
  45. GET /_analyze
  46. {
  47. "tokenizer": "icu_tokenizer",
  48. "text": "I live in and I'm ‍"
  49. }
  50. 上面使用 icu_tokenizer 来对 I live in and I'm ‍” 进行分词。 ‍ 表情符号非常独特,因为它是更经典的 和 表情符号的组合。 中国的国旗也很特别,它是 和 的组合。 因此,我们不仅在谈论正确地分割 Unicode 代码点,而且在这里真正地了解了表情符号。
  51. 上面的请求的返回结果为:
  52. {
  53. "tokens" : [
  54. {
  55. "token" : "I",
  56. "start_offset" : 0,
  57. "end_offset" : 1,
  58. "type" : "<ALPHANUM>",
  59. "position" : 0
  60. },
  61. {
  62. "token" : "live",
  63. "start_offset" : 2,
  64. "end_offset" : 6,
  65. "type" : "<ALPHANUM>",
  66. "position" : 1
  67. },
  68. {
  69. "token" : "in",
  70. "start_offset" : 7,
  71. "end_offset" : 9,
  72. "type" : "<ALPHANUM>",
  73. "position" : 2
  74. },
  75. {
  76. "token" : """""",
  77. "start_offset" : 10,
  78. "end_offset" : 14,
  79. "type" : "<EMOJI>",
  80. "position" : 3
  81. },
  82. {
  83. "token" : "and",
  84. "start_offset" : 16,
  85. "end_offset" : 19,
  86. "type" : "<ALPHANUM>",
  87. "position" : 4
  88. },
  89. {
  90. "token" : "I'm",
  91. "start_offset" : 20,
  92. "end_offset" : 23,
  93. "type" : "<ALPHANUM>",
  94. "position" : 5
  95. },
  96. {
  97. "token" : """""",
  98. "start_offset" : 24,
  99. "end_offset" : 29,
  100. "type" : "<EMOJI>",
  101. "position" : 6
  102. }
  103. ]
  104. }
  105. 显然 emoji 的符号被正确地分词,并能被搜索。
  106. 在实际的使用中,我们可能并不限限于对这些 emoji 的符号的搜索。比如我们想对如下的文档进行搜索:
  107. PUT emoji-capable/_doc/1
  108. {
  109. "content": "I like "
  110. }
  111. 上面的文档中含有一个 ,也就是老虎。针对上面的文档,我们想搜索 tiger 的时候,也能正确地搜索到文档,那么我们该如何去做呢?
  112. 在 github 上面,有一个项目叫做 https://github.com/jolicode/emoji-search/。在它的项目中,有一个目录 https://github.com/jolicode/emoji-search/tree/master/synonyms。这里其实就是同义词的目录。我们现在下载其中的一个文件 https://github.com/jolicode/emoji-search/blob/master/synonyms/cldr-emoji-annotation-synonyms-en.txt 到 Elasticsearch 的本地安装目录:
  113. config
  114. ├── analysis
  115. │ ├── cldr-emoji-annotation-synonyms-en.txt
  116. │ └── emoticons.txt
  117. ├── elasticsearch.yml
  118. ...
  119. 在我的电脑上:
  120. $ pwd
  121. /Users/liuxg/elastic1/elasticsearch-7.11.0/config
  122. $ tree -L 3
  123. .
  124. ├── analysis
  125. │ └── cldr-emoji-annotation-synonyms-en.txt
  126. ├── elasticsearch.keystore
  127. ├── elasticsearch.yml
  128. ├── jvm.options
  129. ├── jvm.options.d
  130. ├── log4j2.properties
  131. ├── role_mapping.yml
  132. ├── roles.yml
  133. ├── users
  134. └── users_roles
  135. 在上面的 cldr-emoji-annotation-synonyms-en.txt 的文件中,它包含了常见 emoji 的符号的同义词。比如:
  136. => , face, grin, grinning face
  137. => , face, grinning face with big eyes, mouth, open, smile
  138. => , eye, face, grinning face with smiling eyes, mouth, open, smile
  139. => , beaming face with smiling eyes, eye, face, grin, smile
  140. => , face, grinning squinting face, laugh, mouth, satisfied, smile
  141. => , cold, face, grinning face with sweat, open, smile, sweat
  142. ....
  143. 为此,我们来进行如下的实验:
  144. PUT /emoji-capable
  145. {
  146. "settings": {
  147. "analysis": {
  148. "filter": {
  149. "english_emoji": {
  150. "type": "synonym",
  151. "synonyms_path": "analysis/cldr-emoji-annotation-synonyms-en.txt"
  152. }
  153. },
  154. "analyzer": {
  155. "english_with_emoji": {
  156. "tokenizer": "icu_tokenizer",
  157. "filter": [
  158. "english_emoji"
  159. ]
  160. }
  161. }
  162. }
  163. },
  164. "mappings": {
  165. "properties": {
  166. "content": {
  167. "type": "text",
  168. "analyzer": "english_with_emoji"
  169. }
  170. }
  171. }
  172. }
  173. 在上面,我们定义了 english_with_emoji 分词器,同时我们在定义 content 字段时也使用相同的分词器 english_with_emoji。我们使用 _analyze API 来进行如下的使用:
  174. GET emoji-capable/_analyze
  175. {
  176. "analyzer": "english_with_emoji",
  177. "text": "I like "
  178. }
  179. 上面的命令返回:
  180. {
  181. "tokens" : [
  182. {
  183. "token" : "I",
  184. "start_offset" : 0,
  185. "end_offset" : 1,
  186. "type" : "<ALPHANUM>",
  187. "position" : 0
  188. },
  189. {
  190. "token" : "like",
  191. "start_offset" : 2,
  192. "end_offset" : 6,
  193. "type" : "<ALPHANUM>",
  194. "position" : 1
  195. },
  196. {
  197. "token" : """""",
  198. "start_offset" : 7,
  199. "end_offset" : 9,
  200. "type" : "SYNONYM",
  201. "position" : 2
  202. },
  203. {
  204. "token" : "tiger",
  205. "start_offset" : 7,
  206. "end_offset" : 9,
  207. "type" : "SYNONYM",
  208. "position" : 2
  209. }
  210. ]
  211. }
  212. 显然它除了返回 , 也同时返回了 tiger 这样的 token。也就是说我们可以同时搜索这两种,都可以搜索到这个文档。同样地:
  213. GET emoji-capable/_analyze
  214. {
  215. "analyzer": "english_with_emoji",
  216. "text": " means happy"
  217. }
  218. 它返回:
  219. {
  220. "tokens" : [
  221. {
  222. "token" : """""",
  223. "start_offset" : 0,
  224. "end_offset" : 2,
  225. "type" : "SYNONYM",
  226. "position" : 0
  227. },
  228. {
  229. "token" : "face",
  230. "start_offset" : 0,
  231. "end_offset" : 2,
  232. "type" : "SYNONYM",
  233. "position" : 0
  234. },
  235. {
  236. "token" : "grin",
  237. "start_offset" : 0,
  238. "end_offset" : 2,
  239. "type" : "SYNONYM",
  240. "position" : 0
  241. },
  242. {
  243. "token" : "grinning",
  244. "start_offset" : 0,
  245. "end_offset" : 2,
  246. "type" : "SYNONYM",
  247. "position" : 0
  248. },
  249. {
  250. "token" : "means",
  251. "start_offset" : 3,
  252. "end_offset" : 8,
  253. "type" : "<ALPHANUM>",
  254. "position" : 1
  255. },
  256. {
  257. "token" : "face",
  258. "start_offset" : 3,
  259. "end_offset" : 8,
  260. "type" : "SYNONYM",
  261. "position" : 1
  262. },
  263. {
  264. "token" : "happy",
  265. "start_offset" : 9,
  266. "end_offset" : 14,
  267. "type" : "<ALPHANUM>",
  268. "position" : 2
  269. }
  270. ]
  271. }
  272. 它表明,如果我们搜索 face, grinning,grin,该文档也会被正确地返回。
  273. 现在,我们输入如下的两个文档:
  274. PUT emoji-capable/_doc/1
  275. {
  276. "content": "I like "
  277. }
  278. PUT emoji-capable/_doc/2
  279. {
  280. "content": " means happy"
  281. }
  282. 我们对文档进行如下的搜索:
  283. GET emoji-capable/_search
  284. {
  285. "query": {
  286. "match": {
  287. "content": ""
  288. }
  289. }
  290. }
  291. 或:
  292. GET emoji-capable/_search
  293. {
  294. "query": {
  295. "match": {
  296. "content": "tiger"
  297. }
  298. }
  299. }
  300. 他们都将返回第一个文档:
  301. {
  302. "took" : 2,
  303. "timed_out" : false,
  304. "_shards" : {
  305. "total" : 1,
  306. "successful" : 1,
  307. "skipped" : 0,
  308. "failed" : 0
  309. },
  310. "hits" : {
  311. "total" : {
  312. "value" : 1,
  313. "relation" : "eq"
  314. },
  315. "max_score" : 0.8514803,
  316. "hits" : [
  317. {
  318. "_index" : "emoji-capable",
  319. "_type" : "_doc",
  320. "_id" : "1",
  321. "_score" : 0.8514803,
  322. "_source" : {
  323. "content" : """I like """
  324. }
  325. }
  326. ]
  327. }
  328. }
  329. 通用地,我们进行如下的搜索:
  330. GET emoji-capable/_search
  331. {
  332. "query": {
  333. "match": {
  334. "content": ""
  335. }
  336. }
  337. }
  338. 或者:
  339. GET emoji-capable/_search
  340. {
  341. "query": {
  342. "match": {
  343. "content": "grin"
  344. }
  345. }
  346. }
  347. 它们都将返回第二个文档:
  348. {
  349. "took" : 1,
  350. "timed_out" : false,
  351. "_shards" : {
  352. "total" : 1,
  353. "successful" : 1,
  354. "skipped" : 0,
  355. "failed" : 0
  356. },
  357. "hits" : {
  358. "total" : {
  359. "value" : 1,
  360. "relation" : "eq"
  361. },
  362. "max_score" : 0.8514803,
  363. "hits" : [
  364. {
  365. "_index" : "emoji-capable",
  366. "_type" : "_doc",
  367. "_id" : "2",
  368. "_score" : 0.8514803,
  369. "_source" : {
  370. "content" : """ means happy"""
  371. }
  372. }
  373. ]
  374. }
  375. }

Elasticsearch:如何实现对 emoji 表情符号进行搜索的更多相关文章

  1. struts2视频学习笔记 22-23(基于XML配置方式实现对action的所有方法及部分方法进行校验)

    课时22 基于XML配置方式实现对action的所有方法进行校验   使用基于XML配置方式实现输入校验时,Action也需要继承ActionSupport,并且提供校验文件,校验文件和action类 ...

  2. 【Struts2学习笔记(11)】对action的输入校验和XML配置方式实现对action的全部方法进行输入校验

    在struts2中,我们能够实现对action的全部方法进行校验或者对action的指定方法进行校验. 对于输入校验struts2提供了两种实现方法: 1. 採用手工编写代码实现. 2. 基于XML配 ...

  3. Android平台中实现对XML的三种解析方式

    本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...

  4. jeecms系统使用介绍——通过二次开发实现对word、pdf、txt等上传附件的全文检索

    转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/76912307 本文出自[我是干勾鱼的博客] 之前在文章<基于Java的门户 ...

  5. 基于DevExpress实现对PDF、Word、Excel文档的预览及操作处理

    http://www.cnblogs.com/wuhuacong/p/4175266.html 在一般的管理系统模块里面,越来越多的设计到一些常用文档的上传保存操作,其中如PDF.Word.Excel ...

  6. C#代码实现对HTTP POST参数进行排序

    private static string GetSortedParas(Dictionary<string, string> dic) { dic = dic.OrderBy(key = ...

  7. 在VS2015中用C++创建DLL并用C#调用且同时实现对DLL的调试

    from:http://m.blog.csdn.net/article/details?id=51075023 在VS2015中先创建C#项目,然后再创建要编写的动态库DLL项目,这样做的好处是整个解 ...

  8. Emoji表情符号录入MySQL数据库报错的解决方案(MySQL utf8与utf8mb4区别)

    本文转自:http://blog.itpub.net/26230597/viewspace-1243233/前言:手机app应用评论的时候,恢复表情符号,提示失败. 1,查看tomcat后台日志,核心 ...

  9. 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】

    一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...

随机推荐

  1. 工作流引擎在vivo营销自动化中的应用实践 | 引擎篇03

    作者:vivo 互联网服务器团队- Cheng Wangrong 本文是<vivo营销自动化技术解密>的第4篇文章,分析了在营销自动化业务引入工作流技术的背景和工作流引擎的介绍,同时介绍了 ...

  2. 教你PC端网易云音乐自定义代理,VIP免费听歌!

    今天分享一份福利吧,使用网易云音乐自定义代理实现免费听和下载VIP.极高音质.付费的歌曲,这里主要针对PC端电脑版的,需要自己写脚本运行. 01 安装node.js Node.js是一个让 JavaS ...

  3. 枚举子集为什么是 O(3^n) 的

    这是更新日志 \(2021/2/9\) 代数推导 \(2021/2/10\) 组合意义,构建 TOC 目录 枚举子集 复杂度证明 代数推导 组合意义 Summary 枚举子集 枚举子集为什么是 \(O ...

  4. 【原创】Selenium获取请求头、响应头

    本文仅供学习交流使用,如侵立删! Selenium获取请求头.响应头 操作环境 win10 . mac Python3.9 selenium.seleniumwire selenium是没有办法直接获 ...

  5. 关于MySQL function创建的限制

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. MySQL 的function创建会有各种限制,经常使用的语句的限制如下: 1.CONTAINS_DYNAMIC_SQL ...

  6. Dolphin Scheduler 1.1.0升级1.2.0避坑指南

    本文章经授权转载 组件介绍 Apache Dolphin Scheduler是一个分布式易扩展的可视化DAG工作流任务调度系统.致力于解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开 ...

  7. (WebFlux)003、多数据源R2dbc事务失效分析

    一.背景 最近项目持续改造,然后把SpringMVC换成了SpringWebflux,然后把Mybatis换成了R2dbc.中间没有遇到什么问题,一切都那么的美滋滋,直到最近一个新需求的出现,打破了往 ...

  8. 【java】学习路径17-StringBuffer、StringBuilder的使用与区别

    本文讲解StringBuffer和StringBuilder的使用与区别. 1-- String String类型我们已经很熟悉了,String一旦被赋值,其在堆中的数据便无法修改. 平时我们的&qu ...

  9. 如何结合整洁架构和MVP模式提升前端开发体验 - 整体架构篇

    本文不详细介绍什么是整洁架构以及 MVP 模式,自行查看文章结尾相关链接文章. 整洁架构粗略介绍 下图为整洁架构最原始的结构图: Entities/Models:实体层,官方说法就是封装了企业里最通用 ...

  10. C++ 对于函数名的操作,函数名本身和取*以及取&的区别

    void TestFunc() { } int _tmain(int argc, _TCHAR* argv[]) { cout<<TestFunc<<endl; cout< ...