一、在Kibana中创建Elasticsearch7.*索引并使用Ik分词的写法
Elasticsearch变化太快,版本间的变化也太大,到了7.*版本之后,网上很多文档都失效了,这是个麻烦的事。在网上找了很多文档资料,但在我搭建的7.7版本Elasticsearch中总是报错。花了些时间才找到问题点。如下为创建一个index:test,同时在此索引下创建一个article的type,结果报错Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters.
1. 创建Elasticsearch7.*索引:
PUT /test
{
"settings": {
"index":{
"refresh_interval": "5s",
"number_of_shards" : 12,
"number_of_replicas" : 1
}
}
}
2. 创建索引同时指定analyzer分词器:
PUT /test
{
"settings": {
"number_of_shards" : 12,
"number_of_replicas" : 1,
"analysis":{
"analyzer":{
"ik":{
"tokenizer":"ik_max_word"
}
}
}
},
"mappings":{
"article":{
"properties":{
"id":{
"type":"long"
},
"title":{
"type":"text",
"analyzer": "ik_max_word"
},
"content":{
"type":"text",
"analyzer": "ik_max_word"
}
}
}
}
}
3. 问题报错:Root mapping definition has unsupported parameters: [article
Elasticsearch从7.4版本起默认不再支持指定索引类型,所有的索引其默认索引类型就是_doc(隐含:include_type_name=false)。
{
"error" : {
"root_cause" : [
{
"type" : "mapper_parsing_exception",
"reason" : "Root mapping definition has unsupported parameters: [article : {properties={id={type=keyword}, title={analyzer=ik_max_word, type=text}, content={analyzer=ik_max_word, type=text}}}]"
}
],
"type" : "mapper_parsing_exception",
"reason" : "Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters: [article : {properties={id={type=keyword}, title={analyzer=ik_max_word, type=text}, content={analyzer=ik_max_word, type=text}}}]",
"caused_by" : {
"type" : "mapper_parsing_exception",
"reason" : "Root mapping definition has unsupported parameters: [article : {properties={id={type=keyword}, title={analyzer=ik_max_word, type=text}, content={analyzer=ik_max_word, type=text}}}]"
}
},
"status" : 400
}
4. 为什么type类型要被移除的猜测
那为什么type类型要被移除呢?我想Elasticsearch也许通过此举让我们更能明白type的意义,平常大家喜欢把索引和关系数据库的库对比,而把type类型和表对比。但这是一个不正确的。
表是相互独立的。但在type类型里字段是相互关联着的,Elasticsearch索引中所有不同类型的同名字段内部使用的是同一个lucene字段存储,两个类型里的user_name必须有一样的字段定义。
在同一个索引中,存储仅有小部分字段相同或者全部字段都不相同的文档,会导致数据稀疏,影响Lucene有效压缩数据的能力。所以Elasticsearch7移除了类型的概念。
而对于上面的这段创建代码,需要修改:mappings下不再需要一层type类型,即一个索引下面的所有type都用的同一个公共的_doc。如下:
5. 创建索引并带IK分词:
PUT /test
{
"settings": {
"number_of_shards" : 12,
"number_of_replicas" : 1,
"analysis":{
"analyzer":{
"ik":{
"tokenizer":"ik_max_word"
}
}
}
},
"mappings":{
"properties":{
"id":{
"type":"long"
},
"title":{
"type":"text",
"analyzer": "ik_max_word"
},
"content":{
"type":"text",
"analyzer": "ik_max_word"
}
}
}
}
二、Elasticsearch:Fatal error: Uncaught Error: Class PsrLogNullLogger
在测试环境执行后台任务的时候碰到报错(PHP环境7.1.33):
Fatal error: Uncaught Error: Class Psr\Log\NullLogger not found in /var/www/vendor/elasticsearch/elasticsearch/src/Elasticsearch/ClientBuilder.php:540 ,
在本地环境执行正常,放到测试服务器上报找不到类。而这些类都是通过vendor加载的。解决办法在composer中添加psr/log配置,更新composer依赖。确保vendor\psr\log目录存在。
#composer.json配置
"php": "^7.0",
"psr/log": "~1.0",
"elasticsearch/elasticsearch": "^6.0"
NullLogger is a class provided by psr/log which is a hard requirement for this package. If you want to install it without composer, the readme tells you to make sure to install dependencies。不过想一下为什么我这在本地开发能正常,放到测试环境才报这个错误呢?
想想有一个可能,我本地的代码提交到仓库时是忽略了log目录的,因为根目录下的log存放的日志不用提交至仓库,而log是一个递归的排除,即psr下的log目录一开始就存在于我本地,只是没有提交仓库。
于是我在本地将log目录改名发现也同样报Psr\Log\NullLogger的错误。说明并不是psr/log不存在,而是未提交到测试环境。因为psr/log目录理论上是在使用composer时自动就会加载的。