介绍:ElasticSearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。Elasticsearch 是用 Java 开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
Elasticsearch中,内置了很多分词器(analyzers)。下面来进行比较下系统默认分词器和常用的中文分词器之间的区别。
系统默认分词器:
1、standard 分词器
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-standard-analyzer.html
如何使用:http://www.yiibai.com/lucene/lucene\_standardanalyzer.html
英文的处理能力同于StopAnalyzer.支持中文采用的方法为单字切分。他会将词汇单元转换成小写形式,并去除停用词和标点符号。
~~~
/**StandardAnalyzer分析器*/
public void standardAnalyzer(String msg){
StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
this.getTokens(analyzer, msg);
~~~
2、simple 分词器
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-simple-analyzer.html
如何使用: http://www.yiibai.com/lucene/lucene\_simpleanalyzer.html
功能强于WhitespaceAnalyzer, 首先会通过非字母字符来分割文本信息,然后将词汇单元统一为小写形式。该分析器会去掉数字类型的字符。
~~~
/**SimpleAnalyzer分析器*/
public void simpleAnalyzer(String msg){
SimpleAnalyzer analyzer = new SimpleAnalyzer(Version.LUCENE_36);
this.getTokens(analyzer, msg);
~~~
3、Whitespace 分词器
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-whitespace-analyzer.html
如何使用:http://www.yiibai.com/lucene/lucene\_whitespaceanalyzer.html
仅仅是去除空格,对字符没有lowcase化,不支持中文; 并且不对生成的词汇单元进行其他的规范化处理。
~~~
/**WhitespaceAnalyzer分析器*/
public void whitespaceAnalyzer(String msg){
WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer(Version.LUCENE_36);
this.getTokens(analyzer, msg);
}
~~~
4、Stop 分词器
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-stop-analyzer.html
如何使用:http://www.yiibai.com/lucene/lucene\_stopanalyzer.html
StopAnalyzer的功能超越了SimpleAnalyzer,在SimpleAnalyzer的基础上增加了去除英文中的常用单词(如the,a等),也可以更加自己的需要设置常用单词;不支持中文
~~~
/**StopAnalyzer分析器*/
public void stopAnalyzer(String msg){
StopAnalyzer analyzer = new StopAnalyzer(Version.LUCENE_36);
this.getTokens(analyzer, msg);
}
~~~
5、keyword 分词器
KeywordAnalyzer把整个输入作为一个单独词汇单元,方便特殊类型的文本进行索引和检索。针对邮政编码,地址等文本信息使用关键词分词器进行索引项建立非常方便。
6、pattern 分词器
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-pattern-analyzer.html
一个pattern类型的analyzer可以通过正则表达式将文本分成"terms"(经过token Filter 后得到的东西 )。接受如下设置:
一个 pattern analyzer 可以做如下的属性设置:
lowercaseterms是否是小写. 默认为 true 小写.pattern正则表达式的pattern, 默认是 \\W+.flags正则表达式的flagsstopwords一个用于初始化stop filter的需要stop 单词的列表.默认单词是空的列表
7、language 分词器
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-lang-analyzer.html
一个用于解析特殊语言文本的analyzer集合。( arabic,armenian, basque, brazilian, bulgarian, catalan, cjk, czech, danish, dutch, english, finnish, french,galician, german, greek, hindi, hungarian, indonesian, irish, italian, latvian, lithuanian, norwegian,persian, portuguese, romanian, russian, sorani, spanish, swedish, turkish, thai.)可惜没有中文。不予考虑
8、snowball 分词器
一个snowball类型的analyzer是由standard tokenizer和standard filter、lowercase filter、stop filter、snowball filter这四个filter构成的。
snowball analyzer 在Lucene中通常是不推荐使用的。
9、Custom 分词器
是自定义的analyzer。允许多个零到多个tokenizer,零到多个 Char Filters. custom analyzer 的名字不能以 "\_"开头.
The following are settings that can be set for a custom analyzer type:
SettingDescriptiontokenizer通用的或者注册的tokenizer.filter通用的或者注册的token filterschar\_filter通用的或者注册的 character filtersposition\_increment\_gap距离查询时,最大允许查询的距离,默认是100
自定义的模板:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
index :
analysis :
analyzer :
myAnalyzer2 :
type : custom
tokenizer : myTokenizer1
filter : [myTokenFilter1, myTokenFilter2]
char_filter : [my_html]
position_increment_gap: 256
tokenizer :
myTokenizer1 :
type : standard
max_token_length : 900
filter :
myTokenFilter1 :
type : stop
stopwords : [stop1, stop2, stop3, stop4]
myTokenFilter2 :
type : length
min : 0
max : 2000
char_filter :
my_html :
type : html_strip
escaped_tags : [xxx, yyy]
read_ahead : 1024
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
### 10、fingerprint 分词器
[https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-fingerprint-analyzer.html](https://link.zhihu.com/?target=https%3A//www.elastic.co/guide/en/elasticsearch/reference/current/analysis-fingerprint-analyzer.html)
* * *
中文分词器:
1、ik-analyzer
https://github.com/wks/ik-analyzer
IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。
采用了特有的“正向迭代最细粒度切分算法“,支持细粒度和最大词长两种切分模式;具有83万字/秒(1600KB/S)的高速处理能力。
采用了多子处理器分析模式,支持:英文字母、数字、中文词汇等分词处理,兼容韩文、日文字符
优化的词典存储,更小的内存占用。支持用户词典扩展定义
针对Lucene全文检索优化的查询分析器IKQueryParser(作者吐血推荐);引入简单搜索表达式,采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高Lucene检索的命中率。
Maven用法:
~~~
<dependency>
<groupId>org.wltea.ik-analyzer</groupId>
<artifactId>ik-analyzer</artifactId>
<version>3.2.8</version>
</dependency>
~~~
在IK Analyzer加入Maven Central Repository之前,你需要手动安装,安装到本地的repository,或者上传到自己的Maven repository服务器上。
要安装到本地Maven repository,使用如下命令,将自动编译,打包并安装: mvn install -Dmaven.test.skip=true
Elasticsearch添加中文分词
安装IK分词插件
https://github.com/medcl/elasticsearch-analysis-ik
进入elasticsearch-analysis-ik-master
更多安装请参考博客:
1、为elastic添加中文分词: http://blog.csdn.net/dingzfang/article/details/42776693
2、如何在Elasticsearch中安装中文分词器(IK+pinyin):http://www.cnblogs.com/xing901022/p/5910139.html
3、Elasticsearch 中文分词器 IK 配置和使用: http://blog.csdn.net/jam00/article/details/52983056
ik 带有两个分词器
ik\_max\_word:会将文本做最细粒度的拆分;尽可能多的拆分出词语
ik\_smart:会做最粗粒度的拆分;已被分出的词语将不会再次被其它词语占有
区别:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
# ik_max_word
curl -XGET 'http://localhost:9200/_analyze?pretty&analyzer=ik_max_word' -d '联想是全球最大的笔记本厂商'
#返回
{
"tokens" : [
{
"token" : "联想",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "是",
"start_offset" : 2,
"end_offset" : 3,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "全球",
"start_offset" : 3,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "最大",
"start_offset" : 5,
"end_offset" : 7,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "的",
"start_offset" : 7,
"end_offset" : 8,
"type" : "CN_CHAR",
"position" : 4
},
{
"token" : "笔记本",
"start_offset" : 8,
"end_offset" : 11,
"type" : "CN_WORD",
"position" : 5
},
{
"token" : "笔记",
"start_offset" : 8,
"end_offset" : 10,
"type" : "CN_WORD",
"position" : 6
},
{
"token" : "本厂",
"start_offset" : 10,
"end_offset" : 12,
"type" : "CN_WORD",
"position" : 7
},
{
"token" : "厂商",
"start_offset" : 11,
"end_offset" : 13,
"type" : "CN_WORD",
"position" : 8
}
]
}
# ik_smart
curl -XGET 'http://localhost:9200/_analyze?pretty&analyzer=ik_smart' -d '联想是全球最大的笔记本厂商'
# 返回
{
"tokens" : [
{
"token" : "联想",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "是",
"start_offset" : 2,
"end_offset" : 3,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "全球",
"start_offset" : 3,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "最大",
"start_offset" : 5,
"end_offset" : 7,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "的",
"start_offset" : 7,
"end_offset" : 8,
"type" : "CN_CHAR",
"position" : 4
},
{
"token" : "笔记本",
"start_offset" : 8,
"end_offset" : 11,
"type" : "CN_WORD",
"position" : 5
},
{
"token" : "厂商",
"start_offset" : 11,
"end_offset" : 13,
"type" : "CN_WORD",
"position" : 6
}
]
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
下面我们来创建一个索引,使用 ik 创建一个名叫 iktest 的索引,设置它的分析器用 ik ,分词器用 ik\_max\_word,并创建一个 article 的类型,里面有一个 subject 的字段,指定其使用 ik\_max\_word 分词器
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
curl -XPUT 'http://localhost:9200/iktest?pretty' -d '{
"settings" : {
"analysis" : {
"analyzer" : {
"ik" : {
"tokenizer" : "ik_max_word"
}
}
}
},
"mappings" : {
"article" : {
"dynamic" : true,
"properties" : {
"subject" : {
"type" : "string",
"analyzer" : "ik_max_word"
}
}
}
}
}'
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
批量添加几条数据,这里我指定元数据 \_id 方便查看,subject 内容为我随便找的几条新闻的标题
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
curl -XPOST http://localhost:9200/iktest/article/_bulk?pretty -d '
{ "index" : { "_id" : "1" } }
{"subject" : ""闺蜜"崔顺实被韩检方传唤 韩总统府促彻查真相" }
{ "index" : { "_id" : "2" } }
{"subject" : "韩举行"护国训练" 青瓦台:决不许国家安全出问题" }
{ "index" : { "_id" : "3" } }
{"subject" : "媒体称FBI已经取得搜查令 检视希拉里电邮" }
{ "index" : { "_id" : "4" } }
{"subject" : "村上春树获安徒生奖 演讲中谈及欧洲排外问题" }
{ "index" : { "_id" : "5" } }
{"subject" : "希拉里团队炮轰FBI 参院民主党领袖批其“违法”" }
'
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
查询 “希拉里和韩国”
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
curl -XPOST http://localhost:9200/iktest/article/_search?pretty -d'
{
"query" : { "match" : { "subject" : "希拉里和韩国" }},
"highlight" : {
"pre_tags" : ["<font color='red'>"],
"post_tags" : ["</font>"],
"fields" : {
"subject" : {}
}
}
}
'
#返回
{
"took" : 113,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 4,
"max_score" : 0.034062363,
"hits" : [ {
"_index" : "iktest",
"_type" : "article",
"_id" : "2",
"_score" : 0.034062363,
"_source" : {
"subject" : "韩举行"护国训练" 青瓦台:决不许国家安全出问题"
},
"highlight" : {
"subject" : [ "<font color=red>韩</font>举行"护<font color=red>国</font>训练" 青瓦台:决不许国家安全出问题" ]
}
}, {
"_index" : "iktest",
"_type" : "article",
"_id" : "3",
"_score" : 0.0076681254,
"_source" : {
"subject" : "媒体称FBI已经取得搜查令 检视希拉里电邮"
},
"highlight" : {
"subject" : [ "媒体称FBI已经取得搜查令 检视<font color=red>希拉里</font>电邮" ]
}
}, {
"_index" : "iktest",
"_type" : "article",
"_id" : "5",
"_score" : 0.006709609,
"_source" : {
"subject" : "希拉里团队炮轰FBI 参院民主党领袖批其“违法”"
},
"highlight" : {
"subject" : [ "<font color=red>希拉里</font>团队炮轰FBI 参院民主党领袖批其“违法”" ]
}
}, {
"_index" : "iktest",
"_type" : "article",
"_id" : "1",
"_score" : 0.0021509775,
"_source" : {
"subject" : ""闺蜜"崔顺实被韩检方传唤 韩总统府促彻查真相"
},
"highlight" : {
"subject" : [ ""闺蜜"崔顺实被<font color=red>韩</font>检方传唤 <font color=red>韩</font>总统府促彻查真相" ]
}
} ]
}
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
这里用了高亮属性 highlight,直接显示到 html 中,被匹配到的字或词将以红色突出显示。若要用过滤搜索,直接将 match 改为 term 即可
热词更新配置
网络词语日新月异,如何让新出的网络热词(或特定的词语)实时的更新到我们的搜索当中呢
先用 ik 测试一下
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
curl -XGET 'http://localhost:9200/_analyze?pretty&analyzer=ik_max_word' -d '
成龙原名陈港生
'
#返回
{
"tokens" : [ {
"token" : "成龙",
"start_offset" : 1,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 0
}, {
"token" : "原名",
"start_offset" : 3,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 1
}, {
"token" : "陈",
"start_offset" : 5,
"end_offset" : 6,
"type" : "CN_CHAR",
"position" : 2
}, {
"token" : "港",
"start_offset" : 6,
"end_offset" : 7,
"type" : "CN_WORD",
"position" : 3
}, {
"token" : "生",
"start_offset" : 7,
"end_offset" : 8,
"type" : "CN_CHAR",
"position" : 4
} ]
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
ik 的主词典中没有”陈港生” 这个词,所以被拆分了。 现在我们来配置一下
修改 IK 的配置文件 :ES 目录/plugins/ik/config/ik/IKAnalyzer.cfg.xml
修改如下:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">custom/mydict.dic;custom/single_word_low_freq.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">custom/ext_stopword.dic</entry>
<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict">http://192.168.1.136/hotWords.php</entry>
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
这里我是用的是远程扩展字典,因为可以使用其他程序调用更新,且不用重启 ES,很方便;当然使用自定义的 mydict.dic 字典也是很方便的,一行一个词,自己加就可以了
既然是远程词典,那么就要是一个可访问的链接,可以是一个页面,也可以是一个txt的文档,但要保证输出的内容是 utf-8 的格式
hotWords.php 的内容
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
$s = <<<'EOF'
陈港生
元楼
蓝瘦
EOF;
header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT', true, 200);
header('ETag: "5816f349-19"');
echo $s;
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
ik 接收两个返回的头部属性 Last-Modified 和 ETag,只要其中一个有变化,就会触发更新,ik 会每分钟获取一次 重启 Elasticsearch ,查看启动记录,看到了三个词已被加载进来
再次执行上面的请求,返回, 就可以看到 ik 分词器已经匹配到了 “陈港生” 这个词,同理一些关于我们公司的专有名字(例如:永辉、永辉超市、永辉云创、云创 .... )也可以自己手动添加到字典中去。
2、结巴中文分词
特点:
1、支持三种分词模式:
精确模式,试图将句子最精确地切开,适合文本分析;
全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
2、支持繁体分词
3、支持自定义词典
3、THULAC
THULAC(THU Lexical Analyzer for Chinese)由清华大学自然语言处理与社会人文计算实验室研制推出的一套中文词法分析工具包,具有中文分词和词性标注功能。THULAC具有如下几个特点:
能力强。利用我们集成的目前世界上规模最大的人工分词和词性标注中文语料库(约含5800万字)训练而成,模型标注能力强大。
准确率高。该工具包在标准数据集Chinese Treebank(CTB5)上分词的F1值可达97.3%,词性标注的F1值可达到92.9%,与该数据集上最好方法效果相当。
速度较快。同时进行分词和词性标注速度为300KB/s,每秒可处理约15万字。只进行分词速度可达到1.3MB/s。
中文分词工具thulac4j发布
1、规范化分词词典,并去掉一些无用词;
2、重写DAT(双数组Trie树)的构造算法,生成的DAT size减少了8%左右,从而节省了内存;
3、优化分词算法,提高了分词速率。
~~~
<dependency>
<groupId>io.github.yizhiru</groupId>
<artifactId>thulac4j</artifactId>
<version>${thulac4j.version}</version>
</dependency>
~~~
[http://www.cnblogs.com/en-heng/p/6526598.html](https://link.zhihu.com/?target=http%3A//www.cnblogs.com/en-heng/p/6526598.html)
thulac4j支持两种分词模式:
SegOnly模式,只分词没有词性标注;
SegPos模式,分词兼有词性标注。
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
// SegOnly mode
String sentence = "滔滔的流水,向着波士顿湾无声逝去";
SegOnly seg = new SegOnly("models/seg_only.bin");
System.out.println(seg.segment(sentence));
// [滔滔, 的, 流水, ,, 向着, 波士顿湾, 无声, 逝去]
// SegPos mode
SegPos pos = new SegPos("models/seg_pos.bin");
System.out.println(pos.segment(sentence));
//[滔滔/a, 的/u, 流水/n, ,/w, 向着/p, 波士顿湾/ns, 无声/v, 逝去/v]
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
4、NLPIR
中科院计算所 NLPIR:http://ictclas.nlpir.org/nlpir/ (可直接在线分析中文)
下载地址:https://github.com/NLPIR-team/NLPIR
中科院分词系统(NLPIR)JAVA简易教程: http://www.cnblogs.com/wukongjiuwo/p/4092480.html
5、ansj分词器
https://github.com/NLPchina/ansj\_seg
这是一个基于n-Gram+CRF+HMM的中文分词的java实现.
分词速度达到每秒钟大约200万字左右(mac air下测试),准确率能达到96%以上
目前实现了.中文分词. 中文姓名识别 .
用户自定义词典,关键字提取,自动摘要,关键字标记等功能 可以应用到自然语言处理等方面,适用于对分词效果要求高的各种项目.
maven 引入:
~~~
<dependency>
<groupId>org.ansj</groupId>
<artifactId>ansj_seg</artifactId>
<version>5.1.1</version>
</dependency>
~~~
调用demo
~~~
String str = "欢迎使用ansj_seg,(ansj中文分词)在这里如果你遇到什么问题都可以联系我.我一定尽我所能.帮助大家.ansj_seg更快,更准,更自由!" ;
System.out.println(ToAnalysis.parse(str));
欢迎/v,使用/v,ansj/en,_,seg/en,,,(,ansj/en,中文/nz,分词/n,),在/p,这里/r,如果/c,你/r,遇到/v,什么/r,问题/n,都/d,可以/v,联系/v,我/r,./m,我/r,一定/d,尽我所能/l,./m,帮助/v,大家/r,./m,ansj/en,_,seg/en,更快/d,,,更/d,准/a,,,更/d,自由/a,!
~~~
6、哈工大的LTP
https://github.com/HIT-SCIR/ltp
LTP制定了基于XML的语言处理结果表示,并在此基础上提供了一整套自底向上的丰富而且高效的中文语言处理模块(包括词法、句法、语义等6项中文处理核心技术),以及基于动态链接库(Dynamic Link Library, DLL)的应用程序接口、可视化工具,并且能够以网络服务(Web Service)的形式进行使用。
关于LTP的使用,请参考: http://ltp.readthedocs.io/zh\_CN/latest/
7、庖丁解牛
下载地址:http://pan.baidu.com/s/1eQ88SZS
使用分为如下几步:
配置dic文件: 修改paoding-analysis.jar中的paoding-dic-home.properties文件,将“#paoding.dic.home=dic”的注释去掉,并配置成自己dic文件的本地存放路径。eg:/home/hadoop/work/paoding-analysis-2.0.4-beta/dic
把Jar包导入到项目中: 将paoding-analysis.jar、commons-logging.jar、lucene-analyzers-2.2.0.jar和lucene-core-2.2.0.jar四个包导入到项目中,这时就可以在代码片段中使用庖丁解牛工具提供的中文分词技术,例如:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
Analyzer analyzer = new PaodingAnalyzer(); //定义一个解析器
String text = "庖丁系统是个完全基于lucene的中文分词系统,它就是重新建了一个analyzer,叫做PaodingAnalyzer,这个analyer的核心任务就是生成一个可以切词TokenStream。"; <span style="font-family: Arial, Helvetica, sans-serif;">//待分词的内容</span>
TokenStream tokenStream = analyzer.tokenStream(text, new StringReader(text)); //得到token序列的输出流
try {
Token t;
while ((t = tokenStream.next()) != null)
{
System.out.println(t); //输出每个token
}
} catch (IOException e) {
e.printStackTrace();
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
8、sogo在线分词
sogo在线分词采用了基于汉字标注的分词方法,主要使用了线性链链CRF(Linear-chain CRF)模型。词性标注模块主要基于结构化线性模型(Structured Linear Model)
在线使用地址为: http://www.sogou.com/labs/webservice/
9、word分词
地址: https://github.com/ysc/word
word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录词。能通过自定义配置文件来改变组件行为,能自定义用户词库、自动检测词库变化、支持大规模分布式环境,能灵活指定多种分词算法,能使用refine功能灵活控制分词结果,还能使用词频统计、词性标注、同义标注、反义标注、拼音标注等功能。提供了10种分词算法,还提供了10种文本相似度算法,同时还无缝和Lucene、Solr、ElasticSearch、Luke集成。注意:word1.3需要JDK1.8
maven 中引入依赖:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
<dependencies>
<dependency>
<groupId>org.apdplat</groupId>
<artifactId>word</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
ElasticSearch插件:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
1、打开命令行并切换到elasticsearch的bin目录
cd elasticsearch-2.1.1/bin
2、运行plugin脚本安装word分词插件:
./plugin install http://apdplat.org/word/archive/v1.4.zip
安装的时候注意:
如果提示:
ERROR: failed to download
或者
Failed to install word, reason: failed to download
或者
ERROR: incorrect hash (SHA1)
则重新再次运行命令,如果还是不行,多试两次
如果是elasticsearch1.x系列版本,则使用如下命令:
./plugin -u http://apdplat.org/word/archive/v1.3.1.zip -i word
3、修改文件elasticsearch-2.1.1/config/elasticsearch.yml,新增如下配置:
index.analysis.analyzer.default.type : "word"
index.analysis.tokenizer.default.type : "word"
4、启动ElasticSearch测试效果,在Chrome浏览器中访问:
http://localhost:9200/_analyze?analyzer=word&text=杨尚川是APDPlat应用级产品开发平台的作者
5、自定义配置
修改配置文件elasticsearch-2.1.1/plugins/word/word.local.conf
6、指定分词算法
修改文件elasticsearch-2.1.1/config/elasticsearch.yml,新增如下配置:
index.analysis.analyzer.default.segAlgorithm : "ReverseMinimumMatching"
index.analysis.tokenizer.default.segAlgorithm : "ReverseMinimumMatching"
这里segAlgorithm可指定的值有:
正向最大匹配算法:MaximumMatching
逆向最大匹配算法:ReverseMaximumMatching
正向最小匹配算法:MinimumMatching
逆向最小匹配算法:ReverseMinimumMatching
双向最大匹配算法:BidirectionalMaximumMatching
双向最小匹配算法:BidirectionalMinimumMatching
双向最大最小匹配算法:BidirectionalMaximumMinimumMatching
全切分算法:FullSegmentation
最少词数算法:MinimalWordCount
最大Ngram分值算法:MaxNgramScore
如不指定,默认使用双向最大匹配算法:BidirectionalMaximumMatching
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
10、jcseg分词器
https://code.google.com/archive/p/jcseg/
11、stanford分词器
Stanford大学的一个开源分词工具,目前已支持汉语。
首先,去【1】下载Download Stanford Word Segmenter version 3.5.2,取得里面的 data 文件夹,放在maven project的 src/main/resources 里。
然后,maven依赖添加:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<corenlp.version>3.6.0</corenlp.version>
</properties>
<dependencies>
<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>${corenlp.version}</version>
</dependency>
<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>${corenlp.version}</version>
<classifier>models</classifier>
</dependency>
<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>${corenlp.version}</version>
<classifier>models-chinese</classifier>
</dependency>
</dependencies>
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
测试:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
import java.util.Properties;
import edu.stanford.nlp.ie.crf.CRFClassifier;
public class CoreNLPSegment {
private static CoreNLPSegment instance;
private CRFClassifier classifier;
private CoreNLPSegment(){
Properties props = new Properties();
props.setProperty("sighanCorporaDict", "data");
props.setProperty("serDictionary", "data/dict-chris6.ser.gz");
props.setProperty("inputEncoding", "UTF-8");
props.setProperty("sighanPostProcessing", "true");
classifier = new CRFClassifier(props);
classifier.loadClassifierNoExceptions("data/ctb.gz", props);
classifier.flags.setProperties(props);
}
public static CoreNLPSegment getInstance() {
if (instance == null) {
instance = new CoreNLPSegment();
}
return instance;
}
public String[] doSegment(String data) {
return (String[]) classifier.segmentString(data).toArray();
}
public static void main(String[] args) {
String sentence = "他和我在学校里常打桌球。";
String ret[] = CoreNLPSegment.getInstance().doSegment(sentence);
for (String str : ret) {
System.out.println(str);
}
}
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
12、Smartcn
Smartcn为Apache2.0协议的开源中文分词系统,Java语言编写,修改的中科院计算所ICTCLAS分词系统。很早以前看到Lucene上多了一个中文分词的contribution,当时只是简单的扫了一下.class文件的文件名,通过文件名可以看得出又是一个改的ICTCLAS的分词系统。
http://lucene.apache.org/core/5\_1\_0/analyzers-smartcn/org/apache/lucene/analysis/cn/smart/SmartChineseAnalyzer.html
13、pinyin 分词器
pinyin分词器可以让用户输入拼音,就能查找到相关的关键词。比如在某个商城搜索中,输入yonghui,就能匹配到永辉。这样的体验还是非常好的。
pinyin分词器的安装与IK是一样的。下载地址:https://github.com/medcl/elasticsearch-analysis-pinyin
一些参数请参考 GitHub 的 readme 文档。
这个分词器在1.8版本中,提供了两种分词规则:
pinyin,就是普通的把汉字转换成拼音;
pinyin\_first\_letter,提取汉字的拼音首字母
使用:
1.Create a index with custom pinyin analyzer
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
curl -XPUT http://localhost:9200/medcl/ -d'
{
"index" : {
"analysis" : {
"analyzer" : {
"pinyin_analyzer" : {
"tokenizer" : "my_pinyin"
}
},
"tokenizer" : {
"my_pinyin" : {
"type" : "pinyin",
"keep_separate_first_letter" : false,
"keep_full_pinyin" : true,
"keep_original" : true,
"limit_first_letter_length" : 16,
"lowercase" : true,
"remove_duplicated_term" : true
}
}
}
}
}'
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
2.Test Analyzer, analyzing a chinese name, such as 刘德华
~~~
http://localhost:9200/medcl/_analyze?text=%e5%88%98%e5%be%b7%e5%8d%8e&analyzer=pinyin_analyzer
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
{
"tokens" : [
{
"token" : "liu",
"start_offset" : 0,
"end_offset" : 1,
"type" : "word",
"position" : 0
},
{
"token" : "de",
"start_offset" : 1,
"end_offset" : 2,
"type" : "word",
"position" : 1
},
{
"token" : "hua",
"start_offset" : 2,
"end_offset" : 3,
"type" : "word",
"position" : 2
},
{
"token" : "刘德华",
"start_offset" : 0,
"end_offset" : 3,
"type" : "word",
"position" : 3
},
{
"token" : "ldh",
"start_offset" : 0,
"end_offset" : 3,
"type" : "word",
"position" : 4
}
]
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
3.Create mapping
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
curl -XPOST http://localhost:9200/medcl/folks/_mapping -d'
{
"folks": {
"properties": {
"name": {
"type": "keyword",
"fields": {
"pinyin": {
"type": "text",
"store": "no",
"term_vector": "with_offsets",
"analyzer": "pinyin_analyzer",
"boost": 10
}
}
}
}
}
}'
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
4.Indexing
~~~
curl -XPOST http://localhost:9200/medcl/folks/andy -d'{"name":"刘德华"}'
~~~
5.Let's search
~~~
http://localhost:9200/medcl/folks/_search?q=name:%E5%88%98%E5%BE%B7%E5%8D%8E
curl http://localhost:9200/medcl/folks/_search?q=name.pinyin:%e5%88%98%e5%be%b7
curl http://localhost:9200/medcl/folks/_search?q=name.pinyin:liu
curl http://localhost:9200/medcl/folks/_search?q=name.pinyin:ldh
curl http://localhost:9200/medcl/folks/_search?q=name.pinyin:de+hua
~~~
6.Using Pinyin-TokenFilter
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
curl -XPUT http://localhost:9200/medcl1/ -d'
{
"index" : {
"analysis" : {
"analyzer" : {
"user_name_analyzer" : {
"tokenizer" : "whitespace",
"filter" : "pinyin_first_letter_and_full_pinyin_filter"
}
},
"filter" : {
"pinyin_first_letter_and_full_pinyin_filter" : {
"type" : "pinyin",
"keep_first_letter" : true,
"keep_full_pinyin" : false,
"keep_none_chinese" : true,
"keep_original" : false,
"limit_first_letter_length" : 16,
"lowercase" : true,
"trim_whitespace" : true,
"keep_none_chinese_in_first_letter" : true
}
}
}
}
}'
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
Token Test:刘德华 张学友 郭富城 黎明 四大天王
~~~
curl -XGET http://localhost:9200/medcl1/_analyze?text=%e5%88%98%e5%be%b7%e5%8d%8e+%e5%bc%a0%e5%ad%a6%e5%8f%8b+%e9%83%ad%e5%af%8c%e5%9f%8e+%e9%bb%8e%e6%98%8e+%e5%9b%9b%e5%a4%a7%e5%a4%a9%e7%8e%8b&analyzer=user_name_analyzer
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
{
"tokens" : [
{
"token" : "ldh",
"start_offset" : 0,
"end_offset" : 3,
"type" : "word",
"position" : 0
},
{
"token" : "zxy",
"start_offset" : 4,
"end_offset" : 7,
"type" : "word",
"position" : 1
},
{
"token" : "gfc",
"start_offset" : 8,
"end_offset" : 11,
"type" : "word",
"position" : 2
},
{
"token" : "lm",
"start_offset" : 12,
"end_offset" : 14,
"type" : "word",
"position" : 3
},
{
"token" : "sdtw",
"start_offset" : 15,
"end_offset" : 19,
"type" : "word",
"position" : 4
}
]
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
7.Used in phrase query
(1)、
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
PUT /medcl/
{
"index" : {
"analysis" : {
"analyzer" : {
"pinyin_analyzer" : {
"tokenizer" : "my_pinyin"
}
},
"tokenizer" : {
"my_pinyin" : {
"type" : "pinyin",
"keep_first_letter":false,
"keep_separate_first_letter" : false,
"keep_full_pinyin" : true,
"keep_original" : false,
"limit_first_letter_length" : 16,
"lowercase" : true
}
}
}
}
}
GET /medcl/folks/_search
{
"query": {"match_phrase": {
"name.pinyin": "刘德华"
}}
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
(2)、
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
PUT /medcl/
{
"index" : {
"analysis" : {
"analyzer" : {
"pinyin_analyzer" : {
"tokenizer" : "my_pinyin"
}
},
"tokenizer" : {
"my_pinyin" : {
"type" : "pinyin",
"keep_first_letter":false,
"keep_separate_first_letter" : true,
"keep_full_pinyin" : false,
"keep_original" : false,
"limit_first_letter_length" : 16,
"lowercase" : true
}
}
}
}
}
POST /medcl/folks/andy
{"name":"刘德华"}
GET /medcl/folks/_search
{
"query": {"match_phrase": {
"name.pinyin": "刘德h"
}}
}
GET /medcl/folks/_search
{
"query": {"match_phrase": {
"name.pinyin": "刘dh"
}}
}
GET /medcl/folks/_search
{
"query": {"match_phrase": {
"name.pinyin": "dh"
}}
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
14、Mmseg 分词器
也支持 Elasticsearch
下载地址:https://github.com/medcl/elasticsearch-analysis-mmseg/releases 根据对应的版本进行下载
如何使用:
1、创建索引:
~~~
curl -XPUT http://localhost:9200/index
~~~
2、创建 mapping
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
curl -XPOST http://localhost:9200/index/fulltext/_mapping -d'
{
"properties": {
"content": {
"type": "text",
"term_vector": "with_positions_offsets",
"analyzer": "mmseg_maxword",
"search_analyzer": "mmseg_maxword"
}
}
}'
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
3.Indexing some docs
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
curl -XPOST http://localhost:9200/index/fulltext/1 -d'
{"content":"美国留给伊拉克的是个烂摊子吗"}
'
curl -XPOST http://localhost:9200/index/fulltext/2 -d'
{"content":"公安部:各地校车将享最高路权"}
'
curl -XPOST http://localhost:9200/index/fulltext/3 -d'
{"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}
'
curl -XPOST http://localhost:9200/index/fulltext/4 -d'
{"content":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"}
'
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
4.Query with highlighting(查询高亮)
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
curl -XPOST http://localhost:9200/index/fulltext/_search -d'
{
"query" : { "term" : { "content" : "中国" }},
"highlight" : {
"pre_tags" : ["<tag1>", "<tag2>"],
"post_tags" : ["</tag1>", "</tag2>"],
"fields" : {
"content" : {}
}
}
}
'
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
5、结果:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
{
"took": 14,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 2,
"hits": [
{
"_index": "index",
"_type": "fulltext",
"_id": "4",
"_score": 2,
"_source": {
"content": "中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
},
"highlight": {
"content": [
"<tag1>中国</tag1>驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首 "
]
}
},
{
"_index": "index",
"_type": "fulltext",
"_id": "3",
"_score": 2,
"_source": {
"content": "中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"
},
"highlight": {
"content": [
"均每天扣1艘<tag1>中国</tag1>渔船 "
]
}
}
]
}
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
参考博客:
为elastic添加中文分词: http://blog.csdn.net/dingzfang/article/details/42776693
15、bosonnlp (玻森数据中文分析器)
下载地址:https://github.com/bosondata/elasticsearch-analysis-bosonnlp
如何使用:
运行 ElasticSearch 之前需要在 config 文件夹中修改 elasticsearch.yml 来定义使用玻森中文分析器,并填写玻森 API\_TOKEN 以及玻森分词 API 的地址,即在该文件结尾处添加:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
index:
analysis:
analyzer:
bosonnlp:
type: bosonnlp
API_URL: http://api.bosonnlp.com/tag/analysis
# You MUST give the API_TOKEN value, otherwise it doesn't work
API_TOKEN: *PUT YOUR API TOKEN HERE*
# Please uncomment if you want to specify ANY ONE of the following
# areguments, otherwise the DEFAULT value will be used, i.e.,
# space_mode is 0,
# oov_level is 3,
# t2s is 0,
# special_char_conv is 0.
# More detials can be found in bosonnlp docs:
# http://docs.bosonnlp.com/tag.html
#
#
# space_mode: put your value here(range from 0-3)
# oov_level: put your value here(range from 0-4)
# t2s: put your value here(range from 0-1)
# special_char_conv: put your value here(range from 0-1)
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
需要注意的是
必须在 API\_URL 填写给定的分词地址以及在API\_TOKEN:PUT YOUR API TOKEN HERE中填写给定的玻森数据API\_TOKEN,否则无法使用玻森中文分析器。该 API\_TOKEN 是注册玻森数据账号所获得。
如果配置文件中已经有配置过其他的 analyzer,请直接在 analyzer 下如上添加 bosonnlp analyzer。
如果有多个 node 并且都需要 BosonNLP 的分词插件,则每个 node 下的 yaml 文件都需要如上安装和设置。
另外,玻森中文分词还提供了4个参数(space\_mode,oov\_level,t2s,special\_char\_conv)可满足不同的分词需求。如果取默认值,则无需任何修改;否则,可取消对应参数的注释并赋值。
测试:
建立 index
~~~
curl -XPUT 'localhost:9200/test'
~~~
测试分析器是否配置成功
~~~
curl -XGET 'localhost:9200/test/_analyze?analyzer=bosonnlp&pretty' -d '这是玻森数据分词的测试'
~~~
结果
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
{
"tokens" : [ {
"token" : "这",
"start_offset" : 0,
"end_offset" : 1,
"type" : "word",
"position" : 0
}, {
"token" : "是",
"start_offset" : 1,
"end_offset" : 2,
"type" : "word",
"position" : 1
}, {
"token" : "玻森",
"start_offset" : 2,
"end_offset" : 4,
"type" : "word",
"position" : 2
}, {
"token" : "数据",
"start_offset" : 4,
"end_offset" : 6,
"type" : "word",
"position" : 3
}, {
"token" : "分词",
"start_offset" : 6,
"end_offset" : 8,
"type" : "word",
"position" : 4
}, {
"token" : "的",
"start_offset" : 8,
"end_offset" : 9,
"type" : "word",
"position" : 5
}, {
"token" : "测试",
"start_offset" : 9,
"end_offset" : 11,
"type" : "word",
"position" : 6
} ]
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
配置 Token Filter
现有的 BosonNLP 分析器没有内置 token filter,如果有过滤 Token 的需求,可以利用 BosonNLP Tokenizer 和 ES 提供的 token filter 搭建定制分析器。
步骤
配置定制的 analyzer 有以下三个步骤:
添加 BosonNLP tokenizer 在 elasticsearch.yml 文件中 analysis 下添加 tokenizer, 并在 tokenizer 中添加 BosonNLP tokenizer 的配置:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
index:
analysis:
analyzer:
...
tokenizer:
bosonnlp:
type: bosonnlp
API_URL: http://api.bosonnlp.com/tag/analysis
# You MUST give the API_TOKEN value, otherwise it doesn't work
API_TOKEN: *PUT YOUR API TOKEN HERE*
# Please uncomment if you want to specify ANY ONE of the following
# areguments, otherwise the DEFAULT value will be used, i.e.,
# space_mode is 0,
# oov_level is 3,
# t2s is 0,
# special_char_conv is 0.
# More detials can be found in bosonnlp docs:
# http://docs.bosonnlp.com/tag.html
#
#
# space_mode: put your value here(range from 0-3)
# oov_level: put your value here(range from 0-4)
# t2s: put your value here(range from 0-1)
# special_char_conv: put your value here(range from 0-1)
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
添加 token filter
在 elasticsearch.yml 文件中 analysis 下添加 filter, 并在 filter 中添加所需 filter 的配置(下面例子中,我们以 lowercase filter 为例):
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
index:
analysis:
analyzer:
...
tokenizer:
...
filter:
lowercase:
type: lowercase
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
添加定制的 analyzer
在 elasticsearch.yml 文件中 analysis 下添加 analyzer, 并在 analyzer 中添加定制的 analyzer 的配置(下面例子中,我们把定制的 analyzer 命名为 filter\_bosonnlp):
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
index:
analysis:
analyzer:
...
filter_bosonnlp:
type: custom
tokenizer: bosonnlp
filter: [lowercase]
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
* * *
自定义分词器
虽然Elasticsearch带有一些现成的分析器,然而在分析器上Elasticsearch真正的强大之处在于,你可以通过在一个适合你的特定数据的设置之中组合字符过滤器、分词器、词汇单元过滤器来创建自定义的分析器。
字符过滤器:
字符过滤器 用来 整理 一个尚未被分词的字符串。例如,如果我们的文本是HTML格式的,它会包含像或者这样的HTML标签,这些标签是我们不想索引的。我们可以使用 html清除 字符过滤器 来移除掉所有的HTML标签,并且像把Á转换为相对应的Unicode字符 Á 这样,转换HTML实体。
一个分析器可能有0个或者多个字符过滤器。
分词器:
一个分析器 必须 有一个唯一的分词器。 分词器把字符串分解成单个词条或者词汇单元。 标准 分析器里使用的 标准 分词器 把一个字符串根据单词边界分解成单个词条,并且移除掉大部分的标点符号,然而还有其他不同行为的分词器存在。
词单元过滤器:
经过分词,作为结果的 词单元流 会按照指定的顺序通过指定的词单元过滤器 。
词单元过滤器可以修改、添加或者移除词单元。我们已经提到过 lowercase 和 stop 词过滤器 ,但是在 Elasticsearch 里面还有很多可供选择的词单元过滤器。 词干过滤器 把单词 遏制 为 词干。 ascii\_folding 过滤器移除变音符,把一个像 "très" 这样的词转换为 "tres" 。 ngram 和 edge\_ngram 词单元过滤器 可以产生 适合用于部分匹配或者自动补全的词单元。
创建一个自定义分析器
我们可以在 analysis 下的相应位置设置字符过滤器、分词器和词单元过滤器:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
PUT /my_index
{
"settings": {
"analysis": {
"char_filter": { ... custom character filters ... },
"tokenizer": { ... custom tokenizers ... },
"filter": { ... custom token filters ... },
"analyzer": { ... custom analyzers ... }
}
}
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
这个分析器可以做到下面的这些事:
1、使用 html清除 字符过滤器移除HTML部分。
2、使用一个自定义的 映射 字符过滤器把 & 替换为 "和" :
~~~
"char_filter": {
"&_to_and": {
"type": "mapping",
"mappings": [ "&=> and "]
}
}
~~~
3、使用 标准 分词器分词。
4、小写词条,使用 小写 词过滤器处理。
5、使用自定义 停止 词过滤器移除自定义的停止词列表中包含的词:
~~~
"filter": {
"my_stopwords": {
"type": "stop",
"stopwords": [ "the", "a" ]
}
}
~~~
我们的分析器定义用我们之前已经设置好的自定义过滤器组合了已经定义好的分词器和过滤器:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
"analyzer": {
"my_analyzer": {
"type": "custom",
"char_filter": [ "html_strip", "&_to_and" ],
"tokenizer": "standard",
"filter": [ "lowercase", "my_stopwords" ]
}
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
汇总起来,完整的 创建索引 请求 看起来应该像这样:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
PUT /my_index
{
"settings": {
"analysis": {
"char_filter": {
"&_to_and": {
"type": "mapping",
"mappings": [ "&=> and "]
}},
"filter": {
"my_stopwords": {
"type": "stop",
"stopwords": [ "the", "a" ]
}},
"analyzer": {
"my_analyzer": {
"type": "custom",
"char_filter": [ "html_strip", "&_to_and" ],
"tokenizer": "standard",
"filter": [ "lowercase", "my_stopwords" ]
}}
}}}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
索引被创建以后,使用 analyze API 来 测试这个新的分析器:
~~~
GET /my_index/_analyze?analyzer=my_analyzer
The quick & brown fox
~~~
下面的缩略结果展示出我们的分析器正在正确地运行:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
{
"tokens" : [
{ "token" : "quick", "position" : 2 },
{ "token" : "and", "position" : 3 },
{ "token" : "brown", "position" : 4 },
{ "token" : "fox", "position" : 5 }
]
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
这个分析器现在是没有多大用处的,除非我们告诉 Elasticsearch在哪里用上它。我们可以像下面这样把这个分析器应用在一个 string 字段上:
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
~~~
PUT /my_index/_mapping/my_type
{
"properties": {
"title": {
"type": "string",
"analyzer": "my_analyzer"
}
}
}
~~~
[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码")
最后,感谢原文作者!
- php开发
- 常用技巧
- 字符数组对象
- php换行替换,PHP替换回车换行符的三种方法
- PHP 数组转字符串,与字符串转数组
- php将img中的宽高删除,PHP删除HTML中宽高样式的详解
- php去除换行(回车换行)的三种方法
- php 过滤word 样式
- php如何设置随机数
- 2个比较经典的PHP加密解密函数分享
- php怎么去除小数点后多余的0
- php中判断是一维数组还是二维数组的解决方案
- php 获取数组中出现次数最多的值(重复最多的值)与出现的次数
- PHP过滤掉换行符、特殊空格、制表符等
- PHP中json_endoce转义反斜杠的问题
- PHP过滤Emoji表情和特殊符号的方法
- PHP完美的提取链接正则
- php很牛的图片采集
- 日期处理
- php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法非常简单
- PHP指定时间戳/日期加一天,一年,一周,一月
- 使用php 获取时间今天明天昨天时间戳的详解
- php获得当月的节假日函数(包含周末,年度节假日)
- PHP获取本月起始和截止时间戳
- php 获取每月开始结束时间,php 获取指定月份的开始结束时间戳
- PHP获取今天,昨天,本月,上个月,本年 起始时间戳
- php、mysql查询当天,本周,本月的用法
- php获取两个时间戳之间相隔多少天多少小时多少分多少秒
- 毫秒级时间戳和日期格式转换
- php-倒计时
- 请求提交上传
- php+put+post,Curl和PHP-如何通过PUT,POST,GET通过curl传递json
- PHP put提交和获取数据
- PHP curl put方式上传文件
- 数据导入导出
- PHP快速导入大量数据到数据库的方法
- PHP快速导出百万级数据到CSV或者EXCEL文件
- PHP解析大型Excel表格的库:box/spout
- PHP导入(百万级)Excel表格数据
- PHP如何切割excel大文件
- 使用 PHP_XLSXWriter 代替 PHPExcel 10W+ 数据秒级导出
- 安装php扩展XLSXWriter
- 解决php导入excel表格时获取日期变成浮点数的方法
- xml处理
- PHP XML和数组互相转换
- php解析xml字符串
- php 生成vcf通讯录
- 文件操作相关
- php获取文件后缀的9种方法
- PHP判断远程文件是否存在
- PHP获取文件修改时间,访问时间,inode修改时间
- php获取远程文件大小教程
- php 读取文件并以文件方式下载
- php 把数字转化为大写中文
- 请求响应
- PHP 获取当前访问的URL
- 压缩
- php生成zip压缩包
- PHPMailer
- 整理PHPMailer 发送邮件 邮件内容为html 可以添加多个附件等
- 通达oa
- OA管理员密码忘了怎么办,这里教你分分钟搞定…
- 跨域
- php解决多站点跨域
- php设置samesite cookie,有效防止CSRF
- Chrome 配置samesite=none方式
- Cookie 的 SameSite 属性
- 图片
- php pdf首页截图,PHP_PHP中使用Imagick读取pdf并生成png缩略图实例,pdf生成png首页缩略图
- PHP -- 七牛云 在线视频 获取某一帧作为封面图
- PHP图片压缩方法
- 如何解决PHP curl或file_get_contents下载图片损坏或无法打开的问题
- php远程下载文章中图片并保存源文件名不变
- 详解PHP如何下载采集图片到本地(附代码实例)
- php如何将webp格式图片转为jpeg
- PHP获取远程图片的宽高和体积大小
- php 软件版本号比较
- 使用PHP通过SMTP发送电邮
- 常用正则表达式
- php如何用正则表达式匹配中文
- 用于分割字符串的 PHP preg_match_all 正则表达式
- 性能优化
- php.ini配置调优
- PHP 几种常见超时的设置方法
- PHP函数in_array、array_key_exists和isset效率分析
- php array push 和array_merge 效率谁高,php 通过array_merge()和array+array合并数组的区别和效率比较...
- php 两个数组取交集、并集、差集
- 设置PHP最大连接数及php-fpm 高并发 参数调整
- 小工具
- php 获取代码执行时间和消耗的内存
- PHP如何判断某项扩展是否开启
- centos7.x下php 导出扩展 XLSXWriter 安装
- php生成mysql数据库字典
- PHP 实现 word/excel/ppt 转换为 PDF
- composer的使用
- showdoc sqlite3 找回管理员密码
- php怎么将数组转为xml
- PHP抖音最新视频提取代码
- yii
- Yii2 如何获取Header参数?
- swoole
- Linux下搭建swoole服务的基本步骤
- 相关学习资料
- 带你学习swoole_process详解
- 按照官方文档 在win10下安装 docker for windows easyswoole镜像 挂载目录
- php常用框架
- Hyperf
- 常用算法PHP版
- thinkphp6
- TP6 事件绑定、监听、订阅
- Thinkphp 模板中输出HTML的变量
- Thinkphp6(操作SQL数据库)
- thinkphp6 mysql查询语句对于为null和为空字符串给出特定值处理
- Thinkphp 6 - 连接配置多个数据库并实现自由切换(详细过程及实例demo)
- TP框架中的Db::name 和 dB::table 以及 db('') 的区别
- thinkphp6.0模型篇之模型的软删除
- thinkphp6自定义日志驱动,增加显示全部请求信息
- 其他系统
- 微擎数据库字段字典
- Flutter实现微信支付和iOS IAP支付
- Flutter上线项目实战——苹果内购
- PHP接入苹果支付
- 调试
- php如何获取当前脚本所有加载的文件
- php跟踪所有调用方法,日志方法
- 解析phpstorm + xdebug 远程断点调试
- PHP XDEBUG调试 PHPSTORM配置
- 异常处理
- PHP 出现 502 解决方案
- php 语法解析错误 syntax error unexpected namespace T_NAMESPACE
- Composer 安装与使用
- 数据库相关
- php pdo怎么设置utf8
- php 如何根据最新聊天对用户进行排序
- php lic&fpm
- 让php程序在linux后台执行
- PHPcli模式和fpm模式优缺点在哪里?
- 运行模式
- php运行模式之cli模式
- 自己库
- php批量获取所有公众号粉丝openid
- 地图
- php 判断点在多边形内,php百度地图api判断地址是否在多边形区域内
- PHP,Mysql-根据一个给定经纬度的点,进行附近地点查询
- MySQL 根据经纬度查找排序
- PHP+MySQL获取坐标范围内的数据
- 【百度地图】删除指定覆盖物
- 百度地图多点+画连接线+数字标注
- laravel5.8
- laravel5.8(四)引入自定义常量文件及公共函数文件
- Lumen 查询执行SQL
- 使你的 Laravel 项目模块化
- Laravel 多条件 AND , OR条件组合查询
- Laravel 查询 多个or或者and条件
- laravel redis操作大全
- laravel中外部定义whereIn的用法和where中使用in
- lumen5.8
- 创建laravel5.8 lumen前后台api项目--记录请求和响应日志
- Laravel和Lumen开启SQL日志记录
- Laravel 5.8 常用操作(路径+日志+分页+其他操作)
- 升级php7.4 laravel lumen报错Trying to access array offset on value of type null
- Laravel 任务调度(计划任务,定时任务)
- laravel的command定时任务时间的设置
- Laravel任务调度的简单使用
- laravel单数据库执行事务和多数据库执行事务
- laravel中锁以及事务的简单使用
- 申请其他相关
- 小程序地理位置接口申请
- PHP高并发
- php 高并发下 秒杀处理思路
- 记录 PHP高并发 商品秒杀 问题的 Redis解决方案
- thinkphp3.2
- thinkphp3.2 数据库 AND OR连缀使用
- laravel
- laravel的联表查询with方法的使用
- laravel获取请求路由对应的控制器和方法
- Laravel 模型关联建立与查询
- Laravel多表(3张表以上)with[]关联查询,对关联的模型做条件查询(has,跟join一样结果 )
- Laravel模型属性的隐藏属性、显示属性和临时暴露隐藏属性用法介绍
- aravel获取当前的url以及当前的基础域名方法汇总
- Laravel 模型实现多库查询或者多表映射
- 关于 Laravel 的 with 多表查询问题
- Laravel 模型过滤(Filter)设计
- 懒加载、预加载、with()、load() 傻傻分不清楚?
- laravel模型$castsl属性
- Laravel Query Builder 复杂查询案例:子查询实现分区查询 partition by
- Laravel 模型关联、关联查询、预加载使用实例
- laravel 中with关联查询限定查询字段
- laravel 原生字段查询 whereRaw 和 where(DB::raw(''))
- lavarel - where条件分组查询(orWhere)
- 通过 Laravel 查询构建器实现复杂的查询语句
- 两个结果集合并成一个
- Laravel 对某一列进行筛选然后求和 sum()
- laravel怎么优雅的拼接where,处理whereIn与where数组查询的问题
- laravel查询时判断是否存在数据
- laravel中的whereNull和whereNotNull
- laravel框架中的子查询
- Laravel框架中 orwhere 多条件查询的使用
- Laravel中where的高级使用方法
- laravel复杂的数据库查询(事例)
- laravel多条件查询方法(and,or嵌套查询)
- Laravel 的 where or 查询
- Laravel 进行where 多个or和and的条件查询可用
- 数据库
- mysql
- mysql联合索引(复合索引)详解
- MYSQL 清空表和截断表
- MySQL快速生成大量测试数据(100万、1000万、1亿)
- 提高mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意)
- MySQL常用命令
- MySQL(三)|《千万级大数据查询优化》第一篇:创建高性能的索引
- MySQL(一)|性能分析方法、SQL性能优化和MySQL内部配置优化
- MySQL(二)|深入理解MySQL的四种隔离级别及加锁实现原理
- MySQL(四)|《千万级大数据查询优化》第一篇:创建高性能的索引(补充)
- MySQL(五)|《千万级大数据查询优化》第二篇:查询性能优化(1)
- MySQL(六)|《千万级大数据查询优化》第二篇:查询性能优化(2)
- MySQL(七)|MySQL分库分表的那点事
- Mysql索引优化 Mysql通过索引提升查询效率(第二棒)
- MySQL查询的性能优化(查询缓存、排序跟索引)
- 【总结】MySQL数据库
- MySQL存储引擎、事务日志并发访问以及隔离级别
- 技巧
- 数据库 SQL查询重复记录 方法
- 替换数据库中某个字段中的部分字符
- mysql开启bin log 并查看bin log日志(linux)
- 分表分区
- 千万级别数据的mysql数据表优化
- MYSQL百万级数据,如何优化
- MySQL备份和恢复
- MySQL间隙锁死锁问题
- 小技巧
- 基础
- MySQL中sql_mode参数
- mysql数据库异常
- this is incompatible with sql_mode=only_full_group_by
- mysql安全
- MySQL数据库被比特币勒索及安全调整
- MongoDB
- sql查询
- MYSQL按时间段分组查询当天,每小时,15分钟数据分组
- 高级
- 基于 MySQL + Tablestore 分层存储架构的大规模订单系统实践-架构篇
- 数据库安全
- 服务器被黑,MySQL 数据库遭比特币勒索!该如何恢复?
- 数千台MySQL数据库遭黑客比特币勒索,该怎么破?
- MySQL 数据库规范
- MySQL数据库开发的36条铁律
- Elasticsearch
- 安装与配置
- ElasticSearch关闭重启命令
- 设置ES默认分词器IK analyzer
- 查询
- elasticsearch 模糊查询不分词,实现 mysql like
- elasticSearch多条件高级检索语句,包含多个must、must_not、should嵌套示例,并考虑nested对象的特殊检索
- elasticSearch按字段普通检索,结果高亮
- Elasticsearch 如何实现查询/聚合不区分大小写?
- 索引更新&刷新
- refresh与批量操作的效率
- Elasticsearch 删除type
- 分词器
- ElasticSearch最全分词器比较及使用方法
- 异常错误
- 解决ES因内存不足而无法查询的错误,Data too large, data for [<http_request>]
- linux
- 基本知识
- CentOS7.5 通过wget下载文件到指定目录
- 【CentOS】vi命令
- centos7查看硬盘使用情况
- CentOS7 查看目录大小
- Centos 7下查看当前目录大小及文件个数
- 普通用户sudo\su 到root免密码
- 普通用户切换到root用户下的免密配置方法
- linux 获取进程启动参数,linux查看进程启动及运行时间
- Linux 查看进程
- linux删除文件后不释放磁盘的问题
- Linux查找大文件命令
- linux 如何关闭正在执行的php脚本
- linux三剑客(grep、sed、awk)基本使用
- centos 卸载软件
- centos查看内存、cpu占用、占用前10,前X
- Centos 查看系统状态
- 异常
- 问题解决:Failed to download metadata for repo ‘appstream‘: Cannot prepare internal mirrorlist:...
- php相关
- centos 安装phpize
- Centos7.2下phpize安装php扩展
- 切换版本
- 运营工具
- 资深Linux运维工程师常用的10款软件/工具介绍
- 一款良心的终端连接工具
- 六款Linux常用远程连接工具介绍,看看哪一款最适合你
- Finalshell
- Linux Finalshell连接centos7和文件无显示问题
- WSL2:我在原生的Win10玩转Linux系统
- MobaXterm
- 运维
- linux服务器上定时自动备份数据库,并保留最新5天的数据
- Centos系统开启及关闭端口
- CentOS7开放和关闭端口命令
- Linux中查看所有正在运行的进程
- 防火墙firewall-cmd命令详解
- centos 7.8阿里云服务器挂载 数据盘
- Linux Finalshell连接centos7和文件无显示问题
- Centos7系统端口被占用问题的解决方法
- vi
- 如何在Vim/Vi中复制,剪切和粘贴
- 命令
- [Linux kill进程] kill 进程pid的使用详解
- 备份还原
- Linux的几种备份、恢复系统方式
- Linux系统全盘备份方法
- 相关软件安装
- linux下 lua安装
- python
- 升级pip之后出现sys.stderr.write(f“ERROR: {exc}“)
- lua
- centos源码部署lua-5.3
- deepin
- deepin20.6设置默认的root密码
- 任务相关
- 宝塔定时任务按秒执行
- CentOS 7 定时任务 crontab 入门
- centos7定时任务crontab
- Linux下定时任务的查看及取消
- Linux(CentOS7)定时执行任务Crond详细说明
- Linux 查看所有定时任务
- linux查看所有用户定时任务
- Linux 定时任务(超详细)
- 防火墙
- Centos7开启防火墙及特定端口
- CentOS防火墙操作:开启端口、开启、关闭、配置
- 生成 SSH 密钥(windows+liunx)
- 阿里云,挂载云盘
- 前端
- layui
- layui多文件上传
- layer.msg()弹框,弹框后继续运行
- radio取值
- layui-数据表格排序
- Layui select选择框添加搜索选项功能
- 保持原来样式
- layui表格单元如何自动换行
- layui-laydate时间日历控件使用方法详解
- layui定时刷新数据表格
- layer 延时设置
- layer.open 回调函数
- 【Layui内置方法】layer.msg延时关闭msg对话框(代码案例)
- layui多图上传图片顺序错乱及重复上传解决
- layer.confirm关闭弹窗
- vue
- Vue跨域解决方法
- vue 4.xx.xx版本降级至2.9.6
- vue-cli 2.x升级到3.x版本, 和3.x降级到2.x版本命令
- 最新版Vue或者指定版本
- Vue2.6.11按需模块安装配置
- jQuery
- jQuery在页面加载时动态修改图片尺寸的方法
- jquery操作select(取值,设置选中)
- 日历
- FullCalendar中文文档:Event日程事件
- js
- JS 之 重定向
- javascript截取video视频第一帧作为封面方案
- HTML <video> preload 属性
- jQuery使用ajax提交post数据
- JS截取视频靓丽的帧作为封面
- H5案例分享:移动端touch事件判断滑屏手势的方向
- JS快速获取图片宽高的方法
- win
- Windows环境下curl的使用
- Cygwin
- Windows下安装Cygwin及apt-cyg
- Cygwin 安装、CMake 安装
- mklink命令 详细使用
- Nginx
- Nginx高级篇-性能优化
- Nginx常用命令(Linux)
- linux+docker+nginx如何配置环境并配置域名访问
- Nginx的启动(start),停止(stop)命令
- linux 查看nginx 安装路径
- 安装配置
- Linux 查看 nginx 安装目录和配置文件路径
- 【NGINX入门】3.Nginx的缓存服务器proxy_cache配置
- thinkphp6.0 伪静态失效404(win下)
- 深入
- nginx rewrite及多upstream
- Nginx负载均衡(upstream)
- 专业术语
- 耦合?依赖?耦合和依赖的关系?耦合就是依赖
- PHP常用六大设计模式
- 高可用
- 分布式与集群
- Nginx 实践案例:反向代理单台web;反向代理多组web并实现负载均衡
- 容器
- Docker
- 30 分钟快速入门 Docker 教程
- linux查看正在运行的容器,说说Docker 容器常用命令
- Windows 安装Docker至D盘
- 配置
- win10 快速搭建 lnmp+swoole 环境 ,部署laravel6 与 swoole框架laravel-s项目1
- win10 快速搭建 lnmp+swoole 环境 ,部署laravel6 与 swoole框架laravel-s项目2
- docker 容器重命名
- Linux docker常用命令
- 使用
- docker 搭建php 开发环境 添加扩展redis、swoole、xdebug
- docker 单机部署redis集群
- Docker 退出容器不停止容器运行 并重新进入正在运行的容器
- 进入退出docker容器
- Docker的容器设置随Docker的启动而启动
- 使用异常处理
- docker容器中bash: vi: command not found
- OCI runtime exec failed: exec failed:解决方法
- docker启动容器慢,很慢,特别慢的坑
- 解决windows docker开发thinkphp6启动慢的问题
- 【Windows Docker】docker挂载解决IO速度慢的问题
- Docker的网络配置,导致Docker使用网路很慢的问题及解决办法
- golang工程部署到docker容器
- Docker 容器设置自启动
- 如何优雅地删除Docker镜像和容器(超详细)
- 5 个好用的 Docker 图形化管理工具
- Docker 可能会用到的命令
- Kubernetes
- 消息队列
- RabbitMQ
- php7.3安装使用rabbitMq
- Windows环境PHP如何使用RabbitMQ
- RabbitMQ学习笔记:4369、5672、15672、25672默认端口号修改
- Window10 系统 RabbitMQ的安装和简单使用
- RabbitMQ默认端口
- RabbitMQ可视化界面登录不了解决方案
- RocketMQ
- Kafka
- ActiveMQ
- mqtt
- phpMQTT详解以及处理使用过程中内存耗死问题
- MQTT--物联网(IoT)消息推送协议
- php实现mqtt发布/发送 消息到主题
- Mqtt.js 的WSS链接
- emqx
- 如何在 PHP 项目中使用 MQTT
- emqx 修改dashboard 密码
- 其他
- Windows 系统中单机最大TCP的连接数详解
- EMQX
- Linux系统EMQX设置开机自启
- Centos7 EMQX部署
- docker安装 EMQX 免费版 docker安装并配置持久化到服务器
- 实时数仓
- 网易云音乐基于 Flink + Kafka 的实时数仓建设实践
- 实时数仓-基于Flink1.11的SQL构建实时数仓探索实践
- 安全
- 网站如何保护用户的密码
- 关于web项目sessionID欺骗的问题
- php的sessionid可以伪造,不要用来做防刷新处理了
- DVWA-Weak Session IDs (弱会话)漏洞利用方式
- 保证接口数据安全的10种方案
- cookie和session的窃取
- 万能密码漏洞
- 黑客如何快速查找网站后台地址方法整理
- 网站后台万能密码/10大常用弱口令
- 万能密码漏洞02
- 大多数网站后台管理的几个常见的安全问题注意防范
- token可以被窃取吗_盗取token
- token被劫持[token被劫持如何保证接口安全性]
- PHP给后台管理系统加安全防护机制的一些方案
- php - 重新生成 session ID
- 隐藏响应中的server和X-Powered-By
- PHP会话控制之如何正确设置session_name
- Session攻击001
- PHP防SQL注入代码,PHP 预防CSRF、XSS、SQL注入攻击
- php25个安全实践
- php架构师 系统管理员必须知道的PHP安全实践
- 版本控制
- Linux服务器关联Git,通过执行更新脚本实现代码同步
- PHP通过exec执行git pull
- git 在linux部署并从windows上提交代码到linux
- git上传到linux服务器,git一键部署代码到远程服务器(linux)
- linux更新git命令,使用Linux定时脚本更新服务器的git代码
- git異常
- 如何解决remote: The project you were looking for could not be found
- git status显示大量文件修改的原因是什么
- PHPstorm批量修改文件换行符CRLF为LF
- git使用
- git常用命令大全
- centos git保存账户密码
- GIT 常用命令
- git怎样还原修改
- Git 如何放弃所有本地修改的方法
- Git忽略文件模式改变
- git: 放弃所有本地修改
- Git三种方法从远程仓库拉取指定的某一个分支
- 杂七杂八
- h5视频
- H5浏览器支持播放格式:H264 AVCA的MP4格式,不能转换为mpeg-4格式,
- iOS无法播放MP4视频文件的解决方案 mp4视频iphone播放不了怎么办
- h5点播播放mp4视频遇到的坑,ios的h5不能播放视频等
- 【Linux 并发请求数】支持多少并发请求数
- Linux下Apache服务器并发优化
- 缓存
- redis
- Linux启动PHP的多进程任务与守护redis队列
- 重启redis命令
- golang