并不是巧合
首先「素」和「玄」在汉语中就和「白」「黑」的意思是相同的
所以日语中しろ くろ分别会对应「白」「素」与「玄」「黑」两个汉字,也就是同音不同的写法而已
日语中一个音有对应多个汉字的情况
毕竟汉语中有很多词来表达一个意思,日语只是将这些汉字安装到固有的读音上面,所以才会出现这种情况
这样的例子很多:(表达相同的意思)
はしる:走る 奔る 疾る 馳しる
わらう:笑う 嗤う 咲う
きく:聞く 聴く
にげる:逃げる 遁げる
のばす:延ばす 伸ばす
そら:空 天
ひ:日 陽
网上有份mdx格式的词典文件,内容是六大同义词词典,包含Roget Thesaurus II, Oxford Thesaurus, Merriam's Thesaurus 2 Ed, Roget's A-Z Thesaurus, Chambers Thesaurus, Roget's Super Thesaurus
名字叫Six Thesaurus, google上搜一搜吧
用法如下:
Eternal (无始无终的), 不朽的, 永久的, 永恒的, 如: 1. Eternal-life to the revolutionary martyrs! 革命烈士们永垂不朽!2. Whoever believes in Him shall have eternal life. 所有相信上帝的人都会获得永生。
Imperishable(文学用语) 不会腐烂的;不坏的;不朽的, 3. My memories are within me, imperishable. 我的记忆刻在我的脑海里,永不磨灭。4. They are imperishable and indestructible and thus eternal. 它们亘古不变, 不可摧毁, 所以是永存不朽的.
更多的在“词不离句:英语常用词汇8000分级过关‘’(这里是链接,点击可以切换)。
●不要试图去记那些用法,是记不住的;而是把例句记下来,这样用法也就记住了!通过听录音,复述,默写,就轻松地把句子记住啦!
在英语常用词汇里有哪些词汇是同义词,近义词及易混词呢?《词不离句:英语常用词汇8000分级过关》统计如下:
从上可见,在英语常用的词汇8000多个里,有过半的词汇是同义词,近义词及易混词,这是很多人没想到的,我们都得区分清楚它们的用法。
●●高效的词汇学习方法见这里(从人体器官功能的角度论述为什么听说写高效,并提供具体学习方法,真心想学英语的人绝不可错过,必读!):
Brother Joe007:词不离句:用自带的大杀器去学习英语!大家都知道,雅思写作评分标准中专门有一项是针对词汇丰富度的,它要求考生能够使用多种多样的表达。但是,大家经常都有这样一个疑惑,明明自己单词背了一大把,为什么作文写出来还是小学生作文呢?
A.可以应付听写,知道单词的词性,能够在阅读中理解这个单词,甚至知道这个单词出现在单词书的哪一页以及哪个位置;
B. 知道一个单词的字表意、引申义,知道这个单词的词根词缀构成,知道这个单词的常用搭配,同义词,反义词,所属话题,同根词。
能够查到同义词的地方有很多,这里给大家推荐两个资源,一个是《牛津英语同义词学习词典》,另一个是 https://www.thesaurus.com/ 网站。
Collocations也称为word combinations,词语搭配是指彼此紧密联系的单词的自然组合,例如“pay attention”,“fast food”,“work hard”和“powerful engine”。通过使用一对更适合上下文且具有更精确含义的词语,考生可以更容易地避免过度使用或模棱两可的单词,例如“非常”或者“好的”。这就好比在移植树苗的时候,总是要带上根部的土壤,树苗才能保证成活。
单词如果光是普通的背诵去读一遍,背一遍,再读一遍,再背一遍,通常记忆效果都不会太理想。究其原因,在这个过程中,咱们的大脑并没有高速运转起来。
在这个训练中,你能看到的是一部分单词相关的信息,至于其他的信息需要你自己来填充,通过鞭策自己的大脑回忆来获得。
生成式练习的应用非常广泛,比如在高中英语考试中的完形填空就是一种生成式练习。又如,提升小孩子认知的闪卡,一面是印着一个字词,另一面印着对应的图画的卡牌。让小孩子看其中一面,想另一面,就是很好的训练,其实也是在主动生成信息来填空。
应用生成式训练有两个技巧,一个技巧叫做扩展式练习,这样的练习是多轮次的,第一个轮次需要填充的信息比较少,第二个轮次需要填充的信息多一点,第三个轮次再多一点,这样每次都增加一点,直到最后完全填充。这种逐级上升难度的练习,可以更加帮助学习者适应单词的运用。比如在研究一篇范文的时候,第一次可以先抹去其中的某几个关键的话题词语,让自己做挖空练习。第二次,挖的空可以稍微长一些,比如变成一个意群。到第三次可能只给自己留下一些表示逻辑结构的词语,在这个的基础上去重新构建出范文。但要注意,不能强化错误的答案,比如,在对比完标准答案的文章后,就必须做一件事,要反复把错题的正确的用法反复到这个句子中,去强化对正确答案的记忆。
生成式训练的第二个技巧是轮换练习。比如在记忆单词“rationale”的时候,你可能会采用一个线索“reason的同义词是什么?”。如果每次练习,作为记忆线索的词(reason)都是固定的,那么你强化记忆的是填补出来的那个词(rationale),而记忆线索这个词并没有得到有效的训练。但是如果做轮换练习,就是把线索词和填空词的位置关系对调一下,先给出“rationale”,然后去问它的同义词是什么,这样你就能把两个词都留下深刻的印象。
有呀,是《词不离句:英语常用词汇8000分级过关》,逐级给出同义词的解说,分级统计如下:
●在8000多的英语常用词汇里,有过半的词汇是同义词,近义词及易混词,通过词汇辨析的学习,突破英语词汇学习瓶颈。
页面展示如下:
●简明扼要的注释,一看就十分清晰他们的区别;
●带语音功能,即点即读,让我们听明白他们,大幅提高听力;
●有超级链接,类似的词组,用鼠标一点就出来,达到瞬时切换的效果;
●有专门的检索表,强大的功能带来极高的学习效率!
●●温馨提示:不要试图去记那些用法,是记不住的;而是把例句记下来,这样用法也就记住了!通过听录音,复述,默写,就轻松地把句子记住啦!
详见如下链接:1、网页版访问如下链接:
词不离句:听得懂,说得出,写得出句子来,这样才是真的懂!2、微信版请访问如下链接:
词不离句:英语常用词汇8000分级过关我觉得不是,乐子人以看客找乐为目的,是被动行为,不触发事件。愉悦犯是引发事件再看乐,是主动行为,是以目的在先的实施行为。
我们在日常口语和写作中经常会遇到一些感到模棱两可的词,比如safety/security,job/position/post,cooperate/collaborate,reign/rein等。要区分这些词,除了平时多查词典多积累之外,还可以借助一些专门的工具书,比如同义词辨析词典。同义词辨析词典一般会将含义或外形相近的单词专门归类放在一起比较,以让读者弄清这些词的异同。这里推荐一本同义词词典:牛津英语同义词学习词典
《牛津英语同义词学习词典》最早由牛津大学出版社推出,2010年由商务印书馆引进英文版。这本词典据说是世界上第一部学习型同义词词典,从块头上来看这本词典厚达1000页,收录了超过2000组同义词,讲解了超过17000个单词和短语,词典容量足以让我们应对绝大部分英语使用场景。
《牛津英语同义词学习词典》对同义词的讲解会更加全面和详细,它的主要特点有以下几个:
(1)词典以最常见的词立条,词目下面把本条要讨论的同义词用黑体罗列出来,并且简单说明这几个词的共同含义。除了介绍词组的共同含义之外,词典还给出了这些单词的常见搭配和句型。这是一个很巧妙的设计。一般来说,我们很少会在做阅读和练口语时使用同义词词典,同义词典的使用场景更多是在写作和笔译中,在这种场景中,如何搭配单词,如何考虑上下文就显得尤为关键,而词典的搭配和句型功能可以帮助我们更好地完成这一任务。
(2)对于不容易区分的同义词,词典还有附加说明,比如chance/opportunity在很多情况下可以互换,但词典指出,opportunity的使用场合会更为正式。同时,单词的在某些搭配中不能互换,比如要说job/equal opportunity,而不能说job/equal chance;可以说give somebody a second chance,但不能说give somebody a second opportunity
又比如climb与go up都有“向上爬”的意思,两者有哪些区别呢?词典会告诉你,与go up相比,climb要付出更多努力。比如我们可以说:climb a wall/fence/tree,但不能说go up a wall/fence/tree,因为爬墙、爬篱笆以及爬树都需要费比较大的劲,需要使用climb来表示这一努力。我们可以用somebody climbs the stairs来强调某人费力地爬楼梯或者楼梯很陡,如果只是单纯地表示“上楼梯”,则可以说somebody goes up the stairs.
(3)同义词的定义前面有关于使用场合的说明,比如在同义词组 brave/gallant/fearless/gusty中,gallant带有old-fashioned or literary的标记,说明该词较多用在老式英语或者文学作品中,fearless带有written标记,说明该词通常用在书面语中,而gusty带有informal标志,说明它是非正式表达,一般用在口语或者非正式的书面语中。这些说明能帮助我们根据不同场合选择不同的词,避免在严肃的书面语场景中使用非正式用词,或者在口语中使用太过正式的表达。
除了上面的这几个特点之外,词典的附录也是一大亮点。作者贴心地将词典中的部分单词按照“艺术”、“人物”、“媒体”、“地点”、“观点”、“健康”、“商业”等常见话题分类,同时还设计了针对这些话题的练习题,方便记忆和理解。有需要的同学可以去看一看这本词典。
谈一点业余的理解。
问:“杜鹃不啼,欲闻其啼,如之奈何?”信长曰:“杜鹃不啼,则杀之。”秀吉曰:“子规不啼,则诱之。”家康曰:“蜀魂不啼,则待之。”
众所周知杜鹃子规蜀魂是同一个东西,你甚至叫布谷鸟都没问题。但是这里能不能随意调换顺序呢?不能。子规比杜鹃多一层陌生化的文学处理;而蜀魂在陌生化的同时加了一个用典的文学处理。
试将其全改为杜鹃:
问:“杜鹃不啼,欲闻其啼,如之奈何?”信长曰:“杜鹃不啼,则杀之。”秀吉曰:“杜鹃不啼,则诱之。”家康曰:“杜鹃不啼,则待之。”
文学性差了一些,只有说理/写人的功能在里面了。所以它和上一段有差距。
试将其全改为蜀魂:
问:“蜀魂不啼,欲闻其啼,如之奈何?”信长曰:“蜀魂不啼,则杀之。”秀吉曰:“蜀魂不啼,则诱之。”家康曰:“蜀魂不啼,则待之。”
功能上自然没有变化。但是惊讶地发现与前全杜鹃一段相比文学性居然也几乎没有变化,一样的烂,明明用了高级点的同义词,这一段的文艺程度却和上一段几乎相等,也都和第一段有差距。
在对偶与骈句中
泉水激石,泠泠作响;好鸟相鸣,嘤嘤成韵。蝉则千转不穷,猿则百叫无绝。
试改为“蝉则千转不穷,猿则百叫不绝”甚至“蝉则百叫不绝,猿亦百叫不绝”则表达效果效果大打折扣。在这里必须要用同义词加以形式上的差异,而往往同义词间意思未完全重合的部分可以以互文的方式流动、交换,只是这个例子中变化的是一个虚词而已。
对韵律的要求。
先考虑数个与“交谈”为同义词的词语。如说话,交流,对谈,对话等。可以举出你想的到的所有同义词,写到纸上或手机里。
看下面一段现代小说。
……镜墙是一条一百五十米长、十八米高的单面镜,位于一条方笛一样的回廊之中,占满了一整侧的墙壁。隧道被显得像一份宗教遗迹,可里面却很热闹。人群三三两两地聚作一团,用普通语打趣,不时爆发出响亮的笑声;男人怀抱着爱侣坐在镜前;一个幻化而成的灰鸽从墙前快速飞过,到长廊的尽头后灵巧地折回;有人把自己的化身改成了一张人民币,掉在地上睡觉:整个建筑的人都在这里,盯着镜子里的对方交谈。
试将段末尾“交谈”用同义词替换,例如改为“说话”、“交流”等,在韵律上不如交谈好。从“人群三三两两地…”开始,到“…的对方交谈”结束一段,每个分号中前一个逗号前的字是上声和去声,如“打趣”qù、“飞过”guò、“人民币”bì、“这里”lǐ;每个分号前一个字是平声,如“笑声”shēng、“镜前”qián、“折回”huí,那么这个只能也是平声。而“对谈”的“对”字和前文“镜子里的对方”中对方的对字赘余或重复,则“盯着对方对谈”不如“盯着对方交谈”好(何况在交谈人数上两词已有差异)。所以在这里这个词是不能被同义词替换的。换句话说,即使穷举所有同义词后,诸多同义词里,能用的其实只有这一个。你也可以在这里体会到语言的无力:稍加限制便可能造成无词可用的局面。
在特色排比中,不得不采用同义词替换谓语等:
政治信仰不变、政治立场不移、政治方向不偏。把培铸灵魂作为根本,把增强本事作为核心,把锤炼血性作为关键,把提纯品德作为基础。既要抓住学习重点,也要注意拓展学习领域;既要向书本学习,也要向实践学习;既要向人民群众学习,向专家学者学习,也要向国外有益经验学习。依靠组织抓学,突出干部领学,运用传统引学,形成机制促学。人人皆愿为,人人皆可为,人人皆能为。不喊空洞口号,不做表面文章,不搞应景工程。既扭住问题又科学分析,既正视矛盾又指明出路,既承认难题又绘出前景,既坦言困惑又鼓励奋进。
解析略。
这样各种文体各种成分的同义替换就齐了
原则上只存在客观的相对关系,反对关系是主观判断。
所以包子即可以和米饭相对,也可以和面条相对。
红色即可以和蓝色相对,也可以和橙色相对。
没有必然不可动摇的反对关系,但人可以根据情境给出特定的限制。
别说英语,汉语也是啊。写小说,第一个小哥,好帅呀,第二个小哥还是,好帅呀。这文字太干巴了吧……
不完全是,中文里古人可以作为死人的讳称,比如“而今,我通过化学竞赛走进了985大学,可是为我解惑的曹老已经成了古人”,曹居东教授2021年去世,显然是现代人,但是这里古人表达他已经去世的含义,并不代表他是古代人。
在前面章节中有实践过将ElasticSearch集成Ik分词器,并通过修改IK分词器源码的方式,从而实现MySql远程词库的更新;并在实际使用过程中,在集群中的问题进行改进,增加版本号的方式解决集群环境IK分词器词库生效问题;请参考
加耀:Elasticsearch7.8.0集成IK分词器改源码实现MySql5.7.2实现动态词库实时更新在实际搜索场景中,常常会感觉搜索引擎似乎不是很懂我们;比如我想搜"苹果",我期待也可以搜索出"iphone"相关的内容,搜索"理想"还可以给我召回"理想汽车"相关的内容;
在ES中我们可以通过自定义分词器来实现这样的效果,并且在ES中有很多种方式可以来维护这个同义词;(请先在ES中安装好IK分词器插件)
顾名思义,即在创建ES的Mapping结构的时候,将同义词维护到Mapping中,如下
PUT synonyms_index
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"index": {
"analysis": {
"filter": {
"doc_synonym": {
"type": "synonym",
"synonyms": ["苹果,iphone,ipad","理想,理想汽车"]
}
},
"analyzer": {
"my_doc_syno": {
"type": "custom",
"tokenizer": "ik_smart",
"filter": [
"doc_synonym"
]
}
}
}
}
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "my_doc_syno"
}
}
}
}
如上所述,在上述DSL语句中在创建Mapping的时候在settings中手动创建一个过滤器,在过滤器中定义同义词组,然后再定义一个分词器,名字可以自己自定义,指定一个编译器,然后指定采用上面创建的过滤器;
然后再在mappings中定义字段,指定字段的分词器为我们自己创建的分词器;
完成上述步骤后,可以开始测试上述添加的同义词是否生效
GET synonyms_index/_analyze
{
"field": "name",
"text": "苹果,理想"
}
执行效果如下,和预期的效果是一致的;
在上面的这种方式中,由于同义词需要在Mapping创建的时候进行维护,所以维护成本极高,每次维护基本上都需要重新定义Mapping结构,不具备扩展性;
所以需要进行改造一下,我们可以在服务器上定义一个文本文件,将同义词维护在文本文件中,这样每次需要增删改同义词时,只需要将文本中的内容修改一下即可;
首先,在ES的安装目录下的config目录下新建文件 synonyms.txt,然后在文本中加入同义词如下
苹果,iphone,ipad
理想,理想汽车
完成上述步骤后,我们再来重新定义Mapping结构,如下
PUT synonyms_index
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"analysis": {
"filter": {
"local_doc_filter": {
"type": "synonym",
"synonyms_path": "synonyms.txt"
}
},
"analyzer": {
"ik_syno": {
"type": "custom",
"tokenizer": "ik_smart",
"filter": [
"local_doc_filter"
]
}
}
}
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "ik_syno"
}
}
}
}
在上述DSL语句中,通过自定义过滤器指定同义词文件地址;一样的,通过DSL语句验证一下当前配置是否生效;
可以看到,这种方式方式和前面的方式获得的效果是一样的。相比较上一种方式,可扩展性好了很多。不过这种方式还是有很明显的缺陷,那就是当文件里面的内容发生变化时,ES不会主动触发去加载新的数据,每次需要重启ES或者是重新创建Mapping结构才会触发效果;
同IK分词器一样,有网友基于elasticsearch-analysis-ik插件源码的基础上写了一个ES同义词的插件;和IK分词器一样,扩展了本地文件词库和远程文件词库以及远程rest动态接口词库;源码地址为
bells/elasticsearch-analysis-dynamic-synonym里面有很多代码和IK分词器源码里的代码是一样的;通过github上可以看到,只需要将源码下载下来编码后拷贝到ES安装目录下的plugins/dynamic-synonym目录下解压即可;
远程动态同义词调用接口代码可参考
@GetMapping("/synonym")
public String synonym (HttpServletRequest request, HttpServletResponse response) {
String result = "";
String eTag = request.getHeader("If-None-Match");
Long eTagVersion = request.getHeader("If-Modified-Since") == null ? -1L : Long.parseLong(request.getHeader("If-Modified-Since"));
// 读取数据库,获取数据库中当前同义词版本号 (在数据库中维护一个版本号,当同义词变更时,变更它)
Long dbVersion = synonymVersionMapper.queryVersion();
if (dbVersion > eTagVersion){
List<String> docList = synonymListMapper.querySynonymList();
StringBuilder words = new StringBuilder();
for (String doc : docList) {
words.append(doc);
words.append(System.getProperty("line.separator"));
}
eTagVersion = dbVersion;
result = words.toString();
}
//更新时间
response.setHeader("ETag", eTag);
response.setHeader("Last-Modified", eTagVersion + "");
response.setHeader("Content-Type", "text/plain");
return result;
}
这样,我们再定义Mapping结构如下所示
PUT synonyms_index
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"index": {
"analysis": {
"filter": {
"local_synonym": {
"type": "dynamic_synonym",
"synonyms_path": "synonyms.txt",
"interval": 30
},
"synonym_graph": {
"type": "dynamic_synonym_graph",
"synonyms_path": "http://127.0.0.1:8080/synonym",
"interval": 30
}
},
"analyzer": {
"synonym": {
"tokenizer": "ik_smart",
"filter": [
"synonym_graph"
]
}
}
}
}
}
}
通过上述方式的定义,当服务器上的文件synonyms.txt发生变化时,插件每30秒去查询一次,当发现文件有变化时,则进行重新同步同义词;我这边在本地已测试且已生效。
远程接口的方式也是一样的;这种方式我在本地还没有经过测试,只是写了上述的伪代码;
由于远程动态同义词词库需要依赖应用程序,所以在考虑是否有更优雅的方式,可以让插件自己去访问数据库,从而实现自主更新;于是可以参考一下第四种方式。
接下来我们一起对dynamic-synonym插件源码改造,使其支持自己访问数据库,读取数据库中的同义词,从而实现词库实时生效;
首先,先从github上下载dynamic-synonym源码到本地,使用编译器打开;
通过pom文件可以看到,当前最新的master分支的代码支持的ES版本是7.7.0,理论上应该也是支持ES7.10.0版本的;不过咱们可以修改一下,将其修改为7.10.0版本;
修改完成后重新编译,此时会发现在代码DynamicSynonymTokenFilterFactory类中有开始报错,是日志相关的;可以把报错的两行代码注释掉,不影响代码逻辑;
// private static final DeprecationLogger DEPRECATION_LOGGER
// = new DeprecationLogger(LogManager.getLogger(DynamicSynonymTokenFilterFactory.class));
和
// DEPRECATION_LOGGER.deprecated(
// "The ignore_case option on the synonym_graph filter is deprecated. " +
// "Instead, insert a lowercase filter in the filter chain before the synonym_graph filter.");
大概看了一下代码,发现和ik分词器插件中的代码很多都比较相似,特别是RemoteSynonymFile类和 ik源码中的Dictionary类尤为相似;
在dynamic-synonym插件代码中有一个接口是 SynonymFile,这个接口为我们提供了扩展性,里面有两个实现,分别是LocalSynonymFile类和RemoteSynonymFile类,其作用分别是读取本地文件获取同义词数据 和 请求远程同义词数据的;
读取远程数据库资源,我们在项目的跟目录下新建一个文件夹config,新建数据库配置文件jdbc-reload.properties,配置如下
然后我们再来完善MySqlRemoteSynonymFile类中的代码,完整代码如下
package com.bellszhu.elasticsearch.plugin.synonym.analysis;
import com.bellszhu.elasticsearch.plugin.DynamicSynonymPlugin;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.synonym.SynonymMap;
import org.elasticsearch.common.io.PathUtils;
import org.elasticsearch.env.Environment;
import java.io.*;
import java.nio.file.Path;
import java.sql.*;
import java.util.ArrayList;
import java.util.Properties;
public class MySqlRemoteSynonymFile implements SynonymFile{
private final static String DB_PROPERTIES = "jdbc-reload.properties";
private static Logger logger = LogManager.getLogger("dynamic-synonym");
private String format;
private boolean expand;
private boolean lenient;
private Analyzer analyzer;
private Environment env;
// 数据库配置
private String location;
// 数据库地址
private static final String jdbcUrl = "jdbc.url";
// 数据库用户名
private static final String jdbcUser = "jdbc.user";
// 数据库密码
private static final String jdbcPassword = "jdbc.password";
private long thisSynonymVersion = -1L;
private Connection connection = null;
private Statement statement = null;
private Properties props;
private Path conf_dir;
MySqlRemoteSynonymFile(Environment env, Analyzer analyzer,
boolean expand, boolean lenient, String format, String location) {
this.analyzer = analyzer;
this.expand = expand;
this.format = format;
this.lenient = lenient;
this.env = env;
this.location = location;
this.props = new Properties();
//读取当前 jar 包存放的路径
Path filePath = PathUtils.get(new File(DynamicSynonymPlugin.class.getProtectionDomain().getCodeSource()
.getLocation().getPath())
.getParent(), "config")
.toAbsolutePath();
this.conf_dir = filePath.resolve(DB_PROPERTIES);
//判断文件是否存在
File configFile = conf_dir.toFile();
InputStream input = null;
try {
input = new FileInputStream(configFile);
} catch (FileNotFoundException e) {
logger.info("jdbc-reload.properties 数据库配置文件没有找到, " + e);
}
if (input != null) {
try {
props.load(input);
} catch (IOException e) {
logger.error("数据库配置文件 jdbc-reload.properties 加载失败," + e);
}
}
isNeedReloadSynonymMap();
}
@Override
public SynonymMap reloadSynonymMap() {
try {
logger.info("start reload local synonym from {}.", location);
Reader rulesReader = getReader();
SynonymMap.Builder parser = RemoteSynonymFile.getSynonymParser(rulesReader, format, expand, lenient, analyzer);
return parser.build();
} catch (Exception e) {
logger.error("reload local synonym {} error!", e, location);
throw new IllegalArgumentException(
"could not reload local synonyms file to build synonyms", e);
}
}
@Override
public boolean isNeedReloadSynonymMap() {
try {
Long mysqlVersion = getMySqlSynonymVersion();
if (thisSynonymVersion < mysqlVersion) {
thisSynonymVersion = mysqlVersion;
return true;
}
} catch (Exception e) {
logger.error(e);
}
return false;
}
public Long getMySqlSynonymVersion() {
ResultSet resultSet = null;
Long mysqlSynonymVersion = 0L;
try {
if (connection == null || statement == null) {
// Class.forName(props.getProperty("jdbc.driver"));
statement = getConnection(props, connection);
}
resultSet = statement.executeQuery(props.getProperty("jdbc.reload.swith.synonym.version"));
while (resultSet.next()) {
mysqlSynonymVersion = resultSet.getLong("swith_state");
logger.info("当前MySql同义词版本号为:{}, 当前节点同义词库版本号为:{}", mysqlSynonymVersion, thisSynonymVersion);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return mysqlSynonymVersion;
}
public ArrayList<String> getDBData() {
ArrayList<String> arrayList = new ArrayList<>();
ResultSet resultSet = null;
try {
if (connection == null || statement == null) {
// Class.forName(props.getProperty("jdbc.driver"));
statement = getConnection(props, connection);
}
logger.info("正在执行SQL查询同义词列表,SQL:{}", props.getProperty("jdbc.reload.synonym.sql"));
resultSet = statement.executeQuery(props.getProperty("jdbc.reload.synonym.sql"));
while (resultSet.next()) {
String theWord = resultSet.getString("words");
arrayList.add(theWord);
}
} catch (SQLException e) {
logger.error(e);
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return arrayList;
}
@Override
public Reader getReader() {
StringBuffer sb = new StringBuffer();
try {
ArrayList<String> dbData = getDBData();
for (int i = 0; i < dbData.size(); i++) {
logger.info("正在加载同义词:{}", dbData.get(i));
// 获取一行一行的记录,每一条记录都包含多个词,形成一个词组,词与词之间使用英文逗号分割
sb.append(dbData.get(i))
.append(System.getProperty("line.separator"));
}
} catch (Exception e) {
logger.error("同义词加载失败");
}
return new StringReader(sb.toString());
}
private static Statement getConnection(Properties props, Connection conn) throws SQLException {
conn = DriverManager.getConnection(
props.getProperty(jdbcUrl),
props.getProperty(jdbcUser),
props.getProperty(jdbcPassword));
return conn.createStatement();
}
}
完成这些后,找到DynamicSynonymTokenFilterFactory类的getSynonymFile(Analyzer analyzer)方法,对其稍加改动,自定义一个类型,触发调用MySql数据库的查询
SynonymFile getSynonymFile(Analyzer analyzer) {
try {
SynonymFile synonymFile;
if ("fromMySql".equals(location)) {
synonymFile = new MySqlRemoteSynonymFile(environment, analyzer, expand, lenient, format, location);
}else if (location.startsWith("http://") || location.startsWith("https://")) {
synonymFile = new RemoteSynonymFile(
environment, analyzer, expand, lenient, format, location);
} else {
synonymFile = new LocalSynonymFile(
environment, analyzer, expand, lenient, format, location);
}
if (scheduledFuture == null) {
scheduledFuture = pool.scheduleAtFixedRate(new Monitor(synonymFile),
interval, interval, TimeUnit.SECONDS);
}
return synonymFile;
} catch (Exception e) {
logger.error("failed to get synonyms: " + location, e);
throw new IllegalArgumentException("failed to get synonyms : " + location, e);
}
}
然后在pom文件中引入jdbc驱动的依赖包
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
到这里,基本上已经接近尾声了;我们需要对源码进行重新编译,不过在编译之前,需要调整一下assemblies目录下的plugin.xml文件,改动后的文件如下
<?xml version="1.0"?>
<assembly>
<id>-</id>
<formats>
<format>zip</format>
</formats>
<includebaseDirectory>false</includebaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}/config</directory>
<outputDirectory>config</outputDirectory>
</fileSet>
</fileSets>
<files>
<file>
<source>${project.basedir}/src/main/resources/plugin-descriptor.properties</source>
<outputDirectory>/</outputDirectory>
<filtered>true</filtered>
</file>
<file>
<source>${project.basedir}/src/main/resources/plugin-security.policy</source>
<outputDirectory>/</outputDirectory>
<filtered>true</filtered>
</file>
</files>
...略...
</assembly>
完成上述步骤后,开始进行源码编译,使用maven依次执行 clean、compile、package,然后在编译后的targer/releases目录下找到编译后的插件安装包文件.zip;
然后在bin目录下启动ES后,新建Mapping使其触发调用数据库逻辑
PUT synonyms_index
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"index": {
"analysis": {
"filter": {
"mysql_synonym": {
"type": "dynamic_synonym",
"synonyms_path": "fromMySql",
"interval": 30
}
},
"analyzer": {
"ik_syno": {
"type": "custom",
"tokenizer": "ik_smart",
"filter": [
"mysql_synonym"
]
},
"ik_syno_max": {
"type": "custom",
"tokenizer": "ik_max_word",
"filter": [
"mysql_synonym"
]
}
}
}
}
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "ik_syno_max",
"search_analyzer": "ik_syno"
},
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
}
在ES的日志中可以看到如下输出
通过日志可以看到,已成功触发数据库同义词词库;因为我本地还有ik分词器访问数据库,所以日志方面有一点干扰;
并且,当数据库中的词库版本号发生变更时,则会触发同步同义词操作;在实际生产环境的应用场景中ES通常是集群搭建,所以采用版本号可以很好的适应集群环境;从而保证每个集群都可以同步生效;
常见问题
常见问题可以参考IK分词器的改源码遇到的问题,基本上问题都是一模一样的;无非以下几种
1、需要在ES的插件目录下,导入MySql的驱动包
2、需要在JDK的安装目录下的指定文件夹下导入MySql的驱动包
3、需要在JDK的安装目录下的指定文件添加一行配置
4、所修改的JDK,需要配置到系统环境变量中,不然ES会采用自带的JDK
ik分词器的采坑地址
加耀:Elasticsearch7.8.0集成IK分词器改源码实现MySql5.7.2实现动态词库实时更新我们在日常口语和写作中经常会遇到一些感到模棱两可的词,比如safety/security,job/position/post,cooperate/collaborate,reign/rein等。要区分这些词,除了平时多查词典多积累之外,还可以借助一些专门的工具书,比如同义词辨析词典。同义词辨析词典一般会将含义或外形相近的单词专门归类放在一起比较,以让读者弄清这些词的异同。这里推荐一本同义词词典:牛津英语同义词学习词典
《牛津英语同义词学习词典》最早由牛津大学出版社推出,2010年由商务印书馆引进英文版。这本词典据说是世界上第一部学习型同义词词典,从块头上来看这本词典厚达1000页,收录了超过2000组同义词,讲解了超过17000个单词和短语,词典容量足以让我们应对绝大部分英语使用场景。
《牛津英语同义词学习词典》对同义词的讲解会更加全面和详细,它的主要特点有以下几个:
(1)词典以最常见的词立条,词目下面把本条要讨论的同义词用黑体罗列出来,并且简单说明这几个词的共同含义。除了介绍词组的共同含义之外,词典还给出了这些单词的常见搭配和句型。这是一个很巧妙的设计。一般来说,我们很少会在做阅读和练口语时使用同义词词典,同义词典的使用场景更多是在写作和笔译中,在这种场景中,如何搭配单词,如何考虑上下文就显得尤为关键,而词典的搭配和句型功能可以帮助我们更好地完成这一任务。
(2)对于不容易区分的同义词,词典还有附加说明,比如chance/opportunity在很多情况下可以互换,但词典指出,opportunity的使用场合会更为正式。同时,单词的在某些搭配中不能互换,比如要说job/equal opportunity,而不能说job/equal chance;可以说give somebody a second chance,但不能说give somebody a second opportunity
又比如climb与go up都有“向上爬”的意思,两者有哪些区别呢?词典会告诉你,与go up相比,climb要付出更多努力。比如我们可以说:climb a wall/fence/tree,但不能说go up a wall/fence/tree,因为爬墙、爬篱笆以及爬树都需要费比较大的劲,需要使用climb来表示这一努力。我们可以用somebody climbs the stairs来强调某人费力地爬楼梯或者楼梯很陡,如果只是单纯地表示“上楼梯”,则可以说somebody goes up the stairs.
(3)同义词的定义前面有关于使用场合的说明,比如在同义词组 brave/gallant/fearless/gusty中,gallant带有old-fashioned or literary的标记,说明该词较多用在老式英语或者文学作品中,fearless带有written标记,说明该词通常用在书面语中,而gusty带有informal标志,说明它是非正式表达,一般用在口语或者非正式的书面语中。这些说明能帮助我们根据不同场合选择不同的词,避免在严肃的书面语场景中使用非正式用词,或者在口语中使用太过正式的表达。
除了上面的这几个特点之外,词典的附录也是一大亮点。作者贴心地将词典中的部分单词按照“艺术”、“人物”、“媒体”、“地点”、“观点”、“健康”、“商业”等常见话题分类,同时还设计了针对这些话题的练习题,方便记忆和理解。有需要的同学可以去看一看这本词典。
在写SCI的时候,有一些表达经常出现:表现了、描述了、为了、根据、增加、降低、产生、推导等等。
虽然这些单词很简单,但是如果通篇只用shown、indicate那两个单词,就会显得自己词汇很少,而且很不native。
审稿人也会觉得文章可读性差,那么很可能就有一个很差的印象分,甚至会拒稿。
为了避免这个情况,
今天就给大家分享自己这几个月写论文时,
总结的一些SCI常用的同义词替换。
- 展现、描述:show、represent、indicate、display、plot、demonstrate、can be seen、depicted、revealed、reflect、address、pinpoint
- 为了:for purpose、in、inorder to、toward、adopt for、for、
- 由于:because、due to、owing to、for、as、in that 、since、through、considering、account into
- 随着:as、over、with、along
- 根据:according to、per-、based on、on the basis of、in the light of、in line with、in accordance with、upon
- 提高、增加:increase、increment、enhance、add、raise、rise、growth、improve、heighten、add、addition、multiply、extend、accrue、boost、elevate
- 降低:reduce、decline、decrease、lower、drop、fall、degrade、minimize、descend、shorten、abate、lessening、diminish
- 削弱:weaken、impair、reduce
- 判断:determine、decide、judge、estimate、verify、check、examine、measure、assess
- 产生:produce、generate、cause、develop、create、form、occurr、appear、grow、create、make、emergence、engendered
- 推导:deduce、educe、derivation、infer、induce
- 同时:at the same time、simultaneously
整理不易,
建议收藏!
一、关于数量(number)
- lots of money=a fortune 一大笔钱
- there are so many=are sprouting up all over the city(or the country/the world)大量出现
- lots of=tons of=loads of= a host of=a multitude of 大量的
二、关于活动(activities)
- play=hang out 玩
- meet=run across=encounter 遇见
- finish=wrap it up 结束
- help someone=do someone a favor帮助
- protect(人)=perserve(资源)保护
- destroy=ruin 破坏
- do sth.=go about sth. 从事
- relax=kick back and relax 休息
- relaxation=leisure=recreation 休闲
- try my best= give it my best shot尽最大努力
- easy=It's a piece of cake=It's a snap=It's a breeze 简单的
- difficult=tough 困难的
- interesting=stimulating 有趣的
- boring=humdrum=mundane=monotonous 没劲的
- enjoy ourselves=have a blast 开心
- painful=grueling 痛苦的
- shout=yell=scream 喊叫
- cheat=con 欺骗
- go to bed=hit the sack=turn in 去睡觉
- make trouble=make waves 制造麻烦
- waste time=idle one's time away 浪费时间
- sit in the sun=catch some rays 晒太阳
- save money=economize 省钱
三、关于物品(things)
- valuable=precious 贵重的
- strange=weird 奇怪的
- expensive=pricey 昂贵的
- cheap=dirt-cheap 便宜的
- fashionable=trendy=stylish=in 时尚的
- popular=in=big=prevalent=ubiquitous=well-liked 流行的
- good taste=chic=classy 有品位的
- a nice thing=a knockout 好东西
- bad products=trash 劣质产品
- old=worn-out=beat-up 老的
- new=brand-new 新的
- huge=enormous=gigantic 巨大的
四、关于人(people)
- my parents=my folks 我的家长
- beautiful=pretty=gorgeous 漂亮的
- fat=overweight 胖的
- thin=slim瘦的
- honest=straightforward=candid=frank直率的
- strong=well-built=well-proportioned 强壮的
- kind=caring=considerate=thoughtful 善良的
- cute=adorable 可爱的
- polite=well-mannered 有礼貌的
- funny=hilarious 搞笑的
- humorous=amusing 幽默的
- busy=tied-up 忙的
- relaxed=refreshed 放松的
- tired=wiped-out=worn-out=bushed 疲劳的
- hungry=starving=famished 饥饿的
- rich=wealthy=affluent 有钱的
- expert=pro 高手
- high-quality(物)=high-caliber(人) 高素质的
- become successful=make it big 成功
- people=individuals=folks 人们
五、关于爱好(hobby)
- like=be into=be fascinated by 喜欢
- hate=dislike=It's not my cup of tea 讨厌
- like and dislike=have mixed feelings about 又爱又恨
- don't know anything about it=don't even have a clue about it 不了解
- depend on=count on 依赖
- happy=delighted 高兴的
- not happy=in a bad mood=upset不高兴
- decide=determine 决定
- can't decide=be torn between A and B无法决定
- sad=in low spirits=blue=down 悲伤
- boring=It's a drag 枯燥的
- moving=touching 感人的
- understand=figure out 理解
- make me angry=It makes my blood boil生气
- be surprised=freak out 吃惊
- feel afraid=get cold feet 害怕
六、关于天气(weather)
- cold=chilly=freezing=frigid 冷的
- cloudy=overcast 阴天的
- hot=scorching 热的
七、关于建筑(buildings)
- tall buildings=high-rise buildings 高楼
- big=spacious 宽敞的
- narrow=cramped 狭小的
- messy=cluttered 混乱的
- quiet=peaceful=tranquil=serene 安静的
- clean=tidy=spotless 干净的
- ugly=It's an eyesore=hideous 丑陋的
- dirty=filthy 脏的
- old=time-honored 历史悠久的
- important=essential 不可缺少的