业务目标:
ES服务中的index "production"需要增加中文分词, 具体效果见下面查询命令输出的对比。
实现过程
- 将数据从mongoDB导入到临时index中;
- 从这个index生成mappings文件;
- 基于上面生成的mappings文件,添加中文分词功能,具体方法见后面"修改mappings文件";
- 根据这个mappings创建index "production";
- 将数据从mongoDB导入到"production"中。
下面是代码实现:
es_ip=192.168.100.90
es="$es_ip:9200"
mongo_ip='192.168.xxx.xxx'
tmp_idx=old_production
idx=production
type=Fair
mapping_file='newfairs-mappings.json'
git clone https://github.com/leetschau/mongo2es.git && cd mongo2es
mongoexport -h $mongo_ip -d $idx -c $type -u xxx -p xxx -o fairs.json
python3 uploadES.py fairs.json $es_ip $tmp_idx $type
http -b --pretty=format $es/$idx/_mapping/$type > $mapping_file
# add "analyzer" into this mapping, see notes below for details
http -b PUT $es/$idx mappings:=@$mapping_file
python3 uploadES.py fairs.json $es_ip $idx $type
http -b POST $es/$tmp_idx/$type/_search query:='{"bool":{"must":[{ "match": { "recurrence.nameZHCN": "五金机械" }}]}}' sort:='[{"recurrence.timeStart": {"order" : "desc", "mode": "max"}}]' size=10 | jq -r '.hits.hits[] | "\(._id): \(._source.recurrence[0].nameZHCN), \(._source.recurrence[0].timeStart)"'
G79B2vwBrHunwkXC6: 国际林业机械和新产品博览会, 2020-06-01T00:00:00.000Z
yXsohQLuRkBXuu8sz: 奥地利林业机械及设备展, 2019-10-08T00:00:00.000Z
uYcC2zMvw9FDutcwk: 金融服务国际展会, 2019-09-26T00:00:00.000Z
BNzwq3WrkH8N7T7tF: 2019年欧洲纺织机械展览会, 2019-06-20T00:00:00.000Z
pkjZjqbd6CSB62Z37: 国际冶金技术展暨研讨会, 2019-06-01T00:00:00.000Z
Rws7ZnBzCSL4AZCMa: 2019年德国国际工程机械、建材机械、矿山机械、工程车辆及设备博览会(2019年第32届德国国际工程机械博览会), 2019-04-01T00:00:00.000Z
GxjMbDrGoiSDoECEN: 2019年德国国际工程机械、建材机械、矿山机械、工程车辆及设备博览会(2019年第32届德国国际工程机械博览会), 2019-04-01T00:00:00.000Z
Kp83k5ciWCNyCapYb: 2019美国际冶金铸造展暨北美铸造年会, 2019-04-01T00:00:00.000Z
LeWCAmhymxxg7Pn64: 机械电子、控制、自动化、植入式电子器材, 2018-10-01T00:00:00.000Z
yD7RtepqLB9QnCSwj: 德国汉诺威国际金属板材加工展, 2018-10-01T00:00:00.000Z
http -b POST $es/$idx/$type/_search query:='{"bool":{"must":[{ "match": { "recurrence.nameZHCN": "五金机械" }}]}}' sort:='[{"recurrence.timeStart": {"order" : "desc", "mode": "max"}}]' size=10 | jq -r '.hits.hits[] | "\(._id): \(._source.recurrence[0].nameZHCN), \(._source.recurrence[0].timeStart)"'
G79B2vwBrHunwkXC6: 国际林业机械和新产品博览会, 2020-06-01T00:00:00.000Z
yXsohQLuRkBXuu8sz: 奥地利林业机械及设备展, 2019-10-08T00:00:00.000Z
BNzwq3WrkH8N7T7tF: 2019年欧洲纺织机械展览会, 2019-06-20T00:00:00.000Z
Rws7ZnBzCSL4AZCMa: 2019年德国国际工程机械、建材机械、矿山机械、工程车辆及设备博览会(2019年第32届德国国际工程机械博览会), 2019-04-01T00:00:00.000Z
GxjMbDrGoiSDoECEN: 2019年德国国际工程机械、建材机械、矿山机械、工程车辆及设备博览会(2019年第32届德国国际工程机械博览会), 2019-04-01T00:00:00.000Z
LeWCAmhymxxg7Pn64: 机械电子、控制、自动化、植入式电子器材, 2018-10-01T00:00:00.000Z
2RQ65WebsKjsPXzby: 南非国际建筑机械、建材机械、矿山机械及工程车辆展, 2018-09-01T00:00:00.000Z
HDj7oxqP92FRHCmfx: 农业机械展(德国), 2018-06-01T00:00:00.000Z
wbPbknwmCeXiYus7w: 德国科隆国际食品加工机械展, 2018-03-20T00:00:00.000Z
rF7utm6WC67R6wGgR: 2018年德国科隆国际五金工具展览会, 2018-03-03T16:00:00.000Z
可以看到临时index的查询结果中,第3、5、8、10项都是没有中文分词导致的错误查询结果, 添加中文分词的正式index中,这些结果都被过滤掉了。
修改mappings文件
使用httpie创建index
为了增加中文分词analyzer:
原有的mappings文件:
{
"production": {
"mappings": {
"Fair": {
"properties": {
"createdAt": {
"format": "strict_date_optional_time||epoch_millis",
"type": "date"
},
"createdBy": {
...
"nameZHCN": {
"type": "string"
},
...
修改后的mappings文件:
{
"Fair": {
"properties": {
"createdAt": {
"format": "strict_date_optional_time||epoch_millis",
"type": "date"
},
"createdBy": {
...
"nameZHCN": {
"type": "string",
"analyzer": "smartcn"
},
...
两方面改动:
-
在
nameZHCN
字段后增加"analyzer": "smartcn", 要改掉mappings中的所有的nameZHCN
,否则可能会报格式冲突; -
mappings文件的格式有变化:要去掉原文件中外层的index名称和
mappings:
, 但"mappings"后面的大括号不要去掉。
在青云上的ES服务上验证通过,他们的ES服务应该安装了smartcn插件, 如果是自己搭建的ES服务,需要手工安装这个插件。
参考:
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-mapping.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-mapping.html
使用curl创建index
使用curl
时需要把mappings
放在mapping文件里,也就是只去掉最外层的``:
{
"mappings": {
"Fair": {
"properties": {
...
然后用curl -i -XPUT ${es_url}/$idx @fair-product-mappings.json
基于这个
mapping文件创建名为"$idx"的index.
创建多个mappings
如果在创建index时需要指定多个type mappings,需要都放在mappings文件里, 不能分开多次执行,否则报 index已存在 错误。
{
"mappings": {
"Fair": {
"properties": {
...
"Product": {
...