1.Elasticsearch7.8.0集成IK分词器改源码实现MySql5.7.2实现动态词库实时更新
2.如何读取elasticsearch的源码分词索引信息
3.Google Aviator——轻量级 Java 表达式引擎实战
4.å¦ä½ç®ä¾¿ä½¿ç¨ikanalyzer
5.叙述使用计算机(击键)输入中文的原理?
6.Unity3d FootIK写一个最简单的IK(1)
Elasticsearch7.8.0集成IK分词器改源码实现MySql5.7.2实现动态词库实时更新
本文旨在探讨 Elasticsearch 7.8.0 集成 IK 分词器的改源码实现,配合 MySQl 5.7.2 实现动态词库实时更新的分析方法。
IK 分词器源码通过 URL 请求文件或接口实现热更新,源码无需重启 ES 实例。分析然而,源码这种方式并不稳定,分析乐博电玩 源码因此,源码采用更为推荐的分析方案,即修改源码实现轮询查询数据库,源码以实现实时更新。分析
在进行配置时,源码需下载 IK 分词器源码,分析并确保 maven 依赖与 ES 版本号相匹配。源码引入 MySQl 驱动后,分析开始对源码进行修改。源码
首先,创建一个名为 HotDictReloadThread 的新类,用于执行远程词库热更新。接着,修改 Dictionary 类的 initial 方法,以创建并启动 HotDictReloadThread 实例,执行字典热更新操作。
在 Dictionary 类中,找到 reLoadMainDict 方法,针对扩展词库维护的逻辑,新增代码加载 MySQl 词库。为此,需预先在数据库中创建一张表,用于维护扩展词和停用词。同时,在项目根路径的 config 目录下创建 jdbc-reload.properties 配置文件,用于数据库连接配置。
通过 jdbc-reload.properties 文件加载数据库连接,执行扩展词 SQL,竞价抓跳空选股指标源码将结果集添加到扩展词库中。类似地,实现同步 MySQl 停用词的逻辑,确保代码的清晰性和可维护性。
完成基础配置后,打包插件并将 MySQl 驱动 mysql-connector-java.jar 与插件一同发布。将插件置于 ES 的 plugins 目录下,并确保有相应的目录结构。启动 ES,查看日志输出,以验证词库更新功能的运行状态。
在此过程中,可能遇到如 Column 'word' not found、Could not create connection to database server、no suitable driver found for jdbc:mysql://...、AccessControlException: access denied 等异常。通过调整 SQL 字段别名、确认驱动版本匹配、确保正确配置环境以及修改 Java 政策文件,这些问题均可得到解决。
本文通过具体步骤和代码示例,详细介绍了 Elasticsearch 7.8.0 集成 IK 分词器,配合 MySQl 5.7.2 实现动态词库实时更新的完整流程。读者可根据本文指南,完成相关配置和代码修改,以实现高效且稳定的词库管理。
如何读取elasticsearch的分词索引信息
一、插件准备
网上有介绍说可以直接用plugin -install medcl/elasticsearch-analysis-ik的办法,但是我执行下来的效果只是将插件的源码下载下来,elasticsearch只是将其作为一个_site插件看待。
所以只有执行maven并将打包后的jar文件拷贝到上级目录。(否则在定义mapping的analyzer的时候会提示找不到类的错误)。
由于IK是头像壁纸表情包取图源码基于字典的分词,所以还要下载IK的字典文件,在medcl的elasticsearch-RTF中有,可以通过这个地址下载:
下载之后解压缩到config目录下。到这里,你可能需要重新启动下elasticsearch,好让下一部定义的分词器能立即生效。
二、分词定义
分词插件准备好之后就可以在elasticsearch里定义(声明)这个分词类型了(自带的几个类型,比如standred则不需要特别定义)。跟其他设置一样,分词的定义也可以在系统级(elasticsearch全局范围),也可以在索引级(只在当前index内部可见)。系统级的定义当然是指在conf目录下的
elasticsearch.yml文件里定义,内容大致如下:
index:
analysis:
analyzer:
ikAnalyzer:
alias: [ik]
type: org.elasticsearch.index.analysis.IkAnalyzerProvider
或者 index.analysis.analyzer.ik.type : "ik"
因为个人喜好,我并没有这么做, 而是定义在了需要使用中文分词的index中,这样定义更灵活,也不会影响其他index。
在定义analyze之前,先关闭index。其实并不需要关闭也可以生效,但是为了数据一致性考虑,还是先执行关闭。(如果是线上的系统需要三思)
curl -XPOST
(很显然,这里的application是我的一个index)
然后执行:
curl -XPUT localhost:/application/_settings -d '
{
"analysis": {
"analyzer":{
"ikAnalyzer":{
"type":"org.elasticsearch.index.analysis.IkAnalyzerProvider",
"alias":"ik"
}
}
}
}
'
打开index:
curl -XPOST
到此为止一个新的类型的分词器就定义好了,接下来就是要如何使用了
或者按如下配置
curl -XPUT localhost:/indexname -d '{
"settings" : {
"analysis" : {
"analyzer" : {
"ik" : {
"tokenizer" : "ik"
}
}
}
},
"mappings" : {
"article" : {
"dynamic" : true,
"properties" : {
"title" : {
"type" : "string",
"analyzer" : "ik"
}
}
}
}
}'
如果我们想返回最细粒度的分词结果,需要在elasticsearch.yml中配置如下:
index:
analysis:
analyzer:
ik:
alias: [ik_analyzer]
type: org.elasticsearch.index.analysis.IkAnalyzerProvider
ik_smart:
type: ik
use_smart: true
ik_max_word:
type: ik
use_smart: false
三、使用分词器
在将分词器使用到实际数据之前,可以先测验下分词效果:
中文分词
分词结果是:
{
"tokens" : [ {
"token" : "中文",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 1
}, {
"token" : "分词",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 2
} ]
}
与使用standard分词器的效果更合理了:
{
"tokens" : [ {
"token" : "中",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<IDEOGRAPHIC>",
"position" : 1
}, {
"token" : "文",
"start_offset" : 1,
"end_offset" : 2,
"type" : "<IDEOGRAPHIC>",
"position" : 2
}, {
"token" : "分",
"start_offset" : 2,
"end_offset" : 3,
"type" : "<IDEOGRAPHIC>",
"position" : 3
}, {
"token" : "词",
"start_offset" : 3,
"end_offset" : 4,
"type" : "<IDEOGRAPHIC>",
"position" : 4
} ]
}
新的分词器定义完成,工作正常后就可以在mapping的定义中引用了,比如我定义这样的type:
curl localhost:/application/article/_mapping -d '
{
"article": {
"properties": {
"description": {
"type": "string",
"indexAnalyzer":"ikAnalyzer",
"searchAnalyzer":"ikAnalyzer"
},
"title": {
"type": "string",
"indexAnalyzer":"ik",
"searchAnalyzer":"ik"
}
}
}
}
'
很遗憾,对于已经存在的index来说,要将一个string类型的源码编程器怎么设置跳跃field从standard的分词器改成别的分词器通常都是失败的:
{
"error": "MergeMappingException[Merge failed with failures { [mapper [description] has different index_analyzer, mapper [description] has
different search_analyzer]}]",
"status":
}
而且没有办法解决冲突,唯一的办法是新建一个索引,并制定mapping使用新的分词器(注意要在数据插入之前,否则会使用elasticsearch默认的分词器)
curl -XPUT localhost:/application/article/_mapping -d '
{
"article" : {
"properties" : {
"description": {
"type": "string",
"indexAnalyzer":"ikAnalyzer",
"searchAnalyzer":"ikAnalyzer"
},
"title": {
"type": "string",
"indexAnalyzer":"ik",
"searchAnalyzer":"ik"
}
}
}
}
至此,一个带中文分词的elasticsearch就算搭建完成。 想偷懒的可以下载medcl的elasticsearch-RTF直接使用,里面需要的插件和配置基本都已经设置好。
------------
标准分词(standard)配置如下:
curl -XPUT localhost:/local -d '{
"settings" : {
"analysis" : {
"analyzer" : {
"stem" : {
"tokenizer" : "standard",
"filter" : ["standard", "lowercase", "stop", "porter_stem"]
}
}
}
},
"mappings" : {
"article" : {
"dynamic" : true,
"properties" : {
"title" : {
"type" : "string",
"analyzer" : "stem"
}
}
}
}
}'
index:local
type:article
default analyzer:stem (filter:小写、停用词等)
field:title
测试:
# Sample Analysis
curl -XGET localhost:/local/_analyze?analyzer=stem -d '{ Fight for your life}'
curl -XGET localhost:/local/_analyze?analyzer=stem -d '{ Bruno fights Tyson tomorrow}'
# Index Data
curl -XPUT localhost:/local/article/1 -d'{ "title": "Fight for your life"}'
curl -XPUT localhost:/local/article/2 -d'{ "title": "Fighting for your life"}'
curl -XPUT localhost:/local/article/3 -d'{ "title": "My dad fought a dog"}'
curl -XPUT localhost:/local/article/4 -d'{ "title": "Bruno fights Tyson tomorrow"}'
# search on the title field, which is stemmed on index and search
curl -XGET localhost:/local/_search?q=title:fight
# searching on _all will not do anystemming, unless also configured on the mapping to be stemmed...
curl -XGET localhost:/local/_search?q=fight
例如:
Fight for your life
分词如下:
{ "tokens":[
{ "token":"fight","start_offset":1,"end_offset":6,"type":"<ALPHANUM>","position":1},<br>
{ "token":"your","start_offset":,"end_offset":,"type":"<ALPHANUM>","position":3},<br>
{ "token":"life","start_offset":,"end_offset":,"type":"<ALPHANUM>","position":4}
]}
-------------------另一篇--------------------
ElasticSearch安装ik分词插件
一、IK简介
IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从年月推出1.0版开始, IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开 始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在版本中,IK实现了简单的分词 歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。
IK Analyzer 特性:
1.采用了特有的逗正向迭代最细粒度切分算法逗,支持细粒度和智能分词两种切分模式;
2.在系统环境:Core2 i7 3.4G双核,4G内存,window 7 位, Sun JDK 1.6_ 位 普通pc环境测试,IK具有万字/秒(KB/S)的高速处理能力。
3.版本的智能分词模式支持简单的分词排歧义处理和数量词合并输出。
4.采用了多子处理器分析模式,支持:英文字母、数字、中文词汇等分词处理,怎么计算二进制源码兼容韩文、日文字符
5.优化的词典存储,更小的内存占用。支持用户词典扩展定义。特别的,在版本,词典支持中文,英文,数字混合词语。
二、安装IK分词插件
假设读者已经安装好ES,如果没有的话,请参考ElasticSearch入门 —— 集群搭建。安装IK分词需要的资源可以从这里下载,整个安装过程需要三个步骤:
1、获取分词的依赖包
通过git clone ,下载分词器源码,然后进入下载目录,执行命令:mvn clean package,打包生成elasticsearch-analysis-ik-1.2.5.jar。将这个jar拷贝到ES_HOME/plugins/analysis-ik目录下面,如果没有该目录,则先创建该目录。
2、ik目录拷贝
将下载目录中的ik目录拷贝到ES_HOME/config目录下面。
3、分词器配置
打开ES_HOME/config/elasticsearch.yml文件,在文件最后加入如下内容:
index:
analysis:
analyzer:
ik:
alias: [ik_analyzer]
type: org.elasticsearch.index.analysis.IkAnalyzerProvider
ik_max_word:
type: ik
use_smart: false
ik_smart:
type: ik
use_smart: true
或
index.analysis.analyzer.default.type: ik
ok!插件安装已经完成,请重新启动ES,接下来测试ik分词效果啦!
三、ik分词测试
1、创建一个索引,名为index。
curl -XPUT
2、为索引index创建mapping。
curl -XPOST /fulltext/_mapping -d'
{
"fulltext": {
"_all": {
"analyzer": "ik"
},
"properties": {
"content": {
"type" : "string",
"boost" : 8.0,
"term_vector" : "with_positions_offsets",
"analyzer" : "ik",
"include_in_all" : true
}
}
}
}'
3、测试
curl '/_analyze?analyzer=ik&pretty=true' -d '
{
"text":"世界如此之大"
}'
显示结果如下:
{
"tokens" : [ {
"token" : "text",
"start_offset" : 4,
"end_offset" : 8,
"type" : "ENGLISH",
"position" : 1
}, {
"token" : "世界",
"start_offset" : ,
"end_offset" : ,
"type" : "CN_WORD",
"position" : 2
}, {
"token" : "如此",
"start_offset" : ,
"end_offset" : ,
"type" : "CN_WORD",
"position" : 3
}, {
"token" : "之大",
"start_offset" : ,
"end_offset" : ,
"type" : "CN_WORD",
"position" : 4
} ]
}
Google Aviator——轻量级 Java 表达式引擎实战
本文将探讨Google Aviator——一款轻量级Java表达式引擎,其在实战中的表现和与其他常用表达式引擎如Drools、IKExpression和Groovy的对比。Drools以其高性能和Java实现闻名,但主要关注复杂对象的规则匹配,而Aviator则定位在轻量级和高性能之间,编译执行模式提供更好的性能。IKExpression作为解释执行的引擎,虽然简洁,但在性能上不如Aviator和Groovy。Groovy凭借动态执行和JIT编译,适用于频繁执行的场景。
在实际场景中,比如监控告警规则配置,Aviator能快速将规则转化为表达式并执行,如示例所示:
通过自定义函数实现,只需继承AbstractAlertFunction,如源码所示,并在初始化时注册。对于性能问题,推荐使用编译缓存模式,以减少每次执行时的编译成本。
Aviator的性能优化和管理可以通过其提供的缓存管理方法来实现。对于更深入的技术探讨和参考,可以参考作者的个人博客和相关文档。
å¦ä½ç®ä¾¿ä½¿ç¨ikanalyzer
IKAnalyzer ç¨æ¥å¯¹ä¸æ®µæéè¿è¡åè¯
IKAnalyzer.cfg.xml æä»¶å¿ é¡»æ¾å¨classpathçæ ¹ç®å½ä¸ï¼å¯ä»¥å¨æºç ä¸ä¿®æ¹è¿ä¸ªé ç½®æ件çä½ç½®ï¼ä½æ¯æ²¡æå¿ è¦å»ä¿®æ¹ã
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "/dtd/properties.dtd">
<properties>
<comment>IK Analyzer æ©å±é ç½®</comment>
<entry key="ext_dict">/ikdic/ext_keyword.dic;</entry>//å¨classpathæ ¹ç®å½ä¸çikdicå ä¸çext_keyword.dic,为æ©å±åå ¸
<entry key="ext_stopwords">/ikdic/ext_stopword.dic</entry> //å¨classpathæ ¹ç®å½ä¸çikdicå ä¸çext_stopword.dic,为åæ¢åå ¸
</properties>
è³äºè°ç¨æ¯å¾ç®åçï¼
package org.bdp.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
public class CZIKAnaUtil {
public static void main(String[] args) {
String str = "æå(-)";
IKAnalysis(str);
}
public static List<String> IKAnalysis(String str) {
List<String> keywordList = new ArrayList<String>();
try {
byte[] bt = str.getBytes();
InputStream ip = new ByteArrayInputStream(bt);
Reader read = new InputStreamReader(ip);
IKSegmenter iks = new IKSegmenter(read,true);//trueå¼å¯åªè½åè¯æ¨¡å¼ï¼å¦æä¸è®¾ç½®é»è®¤ä¸ºfalseï¼ä¹å°±æ¯ç»ç²åº¦åå²
Lexeme t;
while ((t = iks.next()) != null) {
keywordList.add(t.getLexemeText());
}
} catch (IOException e) {
e.printStackTrace();
}
/* for (int i = 0; i < keyWordList.size() - 1; i++) {
for (int j = keyWordList.size() - 1; j > i; j--) {
if (keyWordList.get(j).equals(keyWordList.get(i))) {
keyWordList.remove(j);
}
}
}
Collections.sort(keyWordList, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.length() - o1.length();
}
})*/
System.out.println(keywordList);
return keywordList;
}
}
叙述使用计算机(击键)输入中文的原理?
首先你要对Basic语言有一定了解才可看明白的.
中文输入法的实现过程:
首先,说一下ASCII码与CHR$字符的关系,我们都清楚从0到是文本控制符,到都是英文、数字及
一些常用字符。如:a$ = CHR$() ,对应的 a$ = "A"。而中文字符的ASCII范围是从到。中文字是由两个字
符组成的,所以一个中文字是由两个从到的组合字符构成。如 a$ = CHR$() + CHR$()。对应变量
a$ = "我"。相反如果想知道一个中文字是由那两个ASCII码组成,我们可以将它拆成两个字符,用ASC()函数就可
知道它的相对ASCII码值。如:
PRINT ASC( LEFT$(a$ ,1));
PRINT ASC(RIGHT$(a$ ,1))
结果显示:
现在明白了中文字的ASCII码组合,我们先来做最简单的“区位”输入法。区位输入的码表纯粹是ASCII的
顺序排列。所以我们只要将区位前两位数+,后两位数也+。再将两个数加起来。例如:
QW =
ZWF = QW \ + '区位前两位数+
ZWB = QW MOD + '后两位数+
A$ = CHR$(ZWF) + CHR$(ZWB) '两个数加起来形成区位表码对应的字符
我们看到区位输入法的实现就是如此鸡毛蒜皮的事件。现在我们再来实现“拼音”输入法。如果大家执行以下
代码:
FOR F = TO
FOR B= TO
PRINT CHR$(F) + CHR$(B) ;
NEXT B
NEXT F
稍认真看看规律就不难发现它的ASCII码值是按拼音来排列的。除了声调,拼音的重码是非常多的。这样我们就无须每
个字都作拼音码表检索。反之是用拼音来检索所有重码的字就更简单了。如:输入“wo”,即从(,)开始就
是拼音“wo”所有重码的字符。其它也依次类推。“拼音”输入法虽然没区位简单,但也是不难实现的。用上述的方法
来实现“拼音”输入是最简捷的方法,但存在一个缺点:就是它只能输入日常常用的字,即只是从到之间,算一算
大概有个常用字。还有多个不常用字的排序方法与之不同,后多字是以笔画方式排序的。如果要想实现
一个完整的,就是能输入所有常用及不常用汉字的“拼音”输入法,那么就要专门建立一个“拼音”输入码表检索文件。
在这里就不多谈了。如果有兴趣自己试试。。。。
简单的“拼音”输入法我们都实现了,但“拼音”的输入速度就以它的重码有着莫大的关系。所以我们现在来实现
最常用的、效率高、重码率低、一个我们中国人“王永民”先生设计的输入法“五笔”输入法。这个不用说了,会打
字的一般都认识“五笔”。打五笔我们就打得多了,但“五笔”输入法是如何实现呢?不清楚的QB朋友不用抓头皮,
看下去你就会理直气壮的说:“原来就这么简单!!!”
“五笔”不同于以上“拼音”与“区位”输入法,它在ASCII码表里是没有一个排列规律的,ASCII码这个国际通
用的码表排列,我们是不能随便就更改。既然更改ASCII码表的排列是不可能的事情,我们只好自己做个“五笔”编
码专用的码表好了!!。请看以下源代码程序:
WBX$ = " ggtt=五笔 lwty=输入 ifc=法 yijg=就是 vftc=那么 tuuj=简单 "
WBX$ = WBX$ + " q=我 bn=也 go=来 yaya=试试 rhf=看 drgo=原来 r=的 pugm=实现 " '定义一个基本的码表
CLS
PRINT WBX$
PRINT "请你输入:"
PRINT "原来五笔输入法的实现就是那么的简单我也来试试看"
LOCATE , 5
RecInputChr$ = " " '初始化显示编码及定义光标位置
PRINT "五笔编码: "
DO
IK$ = INKEY$ '读入键盘的ASCII码值
IF IK$ = CHR$() THEN EXIT DO '按ESC键退出
IF IK$ = CHR$() THEN '按Enter键重置编码
InputChr$ = ""
ELSEIF IK$ = CHR$(8) THEN '按BackSpace键后退
IF InputChr$ <> "" THEN InputChr$ = LEFT$(InputChr$, LEN(InputChr$) - 1)
ELSEIF IK$ <> "" AND IK$ <> CHR$() THEN '如果键入的不是空格键而且键盘有键按下时编码字符被键入新编码
InputChr$ = InputChr$ + IK$
END IF
IF IK$ = CHR$() OR LEN(InputChr$) = 4 THEN '如果按了空格键或够4码即执行码表检索
II$ = " " + RTRIM$(InputChr$) + "="
ST = INSTR(1, WBX$, II$)
IF ST > 0 THEN
ST = ST + LEN(InputChr$) + 2
EN = INSTR(ST, WBX$, " ")
IF EN = 0 THEN EN = LEN(WBX$)
ZW$ = MID$(WBX$, ST, EN - ST) '检索到的编码字符
TXT$ = TXT$ + ZW$ '输入栏字符被输入编码的汉字
LOCATE 6, 1: PRINT TXT$ '显示输入的内容
END IF
InputChr$ = "" '编码字符被重置
END IF
IF InputChr$ <> RecInputChr$ THEN '如果当前编码与上次编码有改变即刷新
LOCATE ,
PRINT InputChr$ + " " '显示编码字符
LOCATE 6, LEN(TXT$) + 1, 1 '定义输入栏光标位置
RecInputChr$ = InputChr$ '给上次编码赋最新编码内容值
END IF
LOOP
Unity3d FootIK写一个最简单的IK(1)
前言:
历经无数次尝试与调整,终于找到了在Unity环境中实现FootIK的基本方法。整个过程虽然充满了挑战,但学习到的知识与技巧却让我感到收获满满。
预备设置:
为了使用Unity内部的IK系统,我们需要进行以下步骤的设置。
1. 为FBX模型设置Humanoid Avatar,确保在Avatar设置界面中正确绑定骨骼。
2. 创建并配置AnimatorController,激活特定层级的IK Pass功能。
3. 编写脚本,声明OnAnimatorIK方法,用于处理IK解算。
创建FootIK脚本:
1. 定义脚本中的变量,这些变量将用于后续算法的执行。
2. 在FixedUpdate函数中获取骨骼信息,计算IK位置。
3. 编写AdjustFeetTarget方法,获取脚部Transform的位置,并进行调整以避免模型穿模。
4. 实现FootPositionSolver方法,使用Raycast检测地面位置,计算旋转角度。
动画曲线设置:
在动画中,脚部抬离地面时,需通过动画曲线调整IK目标的权重。通过在FBX Inspector中配置动画曲线,根据动画片段的不同阶段,设置合适的权重值,以实现脚部自然抬起与落地的效果。确保在Animator面板中正确添加Float参数,以便在播放动画时动态调整。
实践与原理:
1. 整理脚本并将其应用到角色GameObject上,激活IK功能,通过设置目标层级,使角色能够在阶梯上自然行走。
2. 讲解算法原理与流程,包括使用简单射线检测计算IK位置,以及在OnAnimatorIK方法中,通过动画曲线动态调整权重,影响骨骼位置。
揭秘Unity IK本质:
深入理解MoveFeetToIkPoint方法的工作原理,包括transform坐标变换、Animator的Getter与Setter机制。发现IK Goal实际上包含了与地面的偏移信息,并通过yVar变量进行动态调整,确保角色脚部贴合地面,防止穿模。了解Unity内部动画计算流程与IK应用顺序,揭示了为何增量赋值能有效控制角色行走。
小结:
通过解析Unity内置的IK系统,对功能插件的原理有了更深入的理解。展望未来,希望能够探索更多高级的IK实现方法,如Final IK与AnimationRigging,进一步提升角色动画效果。同时,源代码的分享将为社区开发者提供参考与灵感,促进Unity生态的共同进步。
elasticsearch ç¨ä»ä¹è¯è¨å¼å
Elasticsearchä¹ä½¿ç¨Javaå¼å并使ç¨Luceneä½ä¸ºå ¶æ ¸å¿æ¥å®ç°ææç´¢å¼åæç´¢çåè½ï¼ä½æ¯å®çç®çæ¯éè¿ç®åçRESTful APIæ¥éèLuceneçå¤ææ§ï¼ä»èè®©å ¨ææç´¢åå¾ç®åã