DarkMatter in Cyberspace
  • Home
  • Categories
  • Tags
  • Archives

为Elasticsearch服务添加中文分词功能


业务目标:

ES服务中的index "production"需要增加中文分词, 具体效果见下面查询命令输出的对比。

实现过程

  1. 将数据从mongoDB导入到临时index中;
  2. 从这个index生成mappings文件;
  3. 基于上面生成的mappings文件,添加中文分词功能,具体方法见后面"修改mappings文件";
  4. 根据这个mappings创建index "production";
  5. 将数据从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"
            }, 
            ...

两方面改动:

  1. 在nameZHCN字段后增加"analyzer": "smartcn", 要改掉mappings中的所有的nameZHCN,否则可能会报格式冲突;

  2. 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": {
             ...


Published

Aug 3, 2016

Last Updated

Aug 3, 2016

Category

Tech

Tags

  • chinese 8
  • elasticsearch 6
  • segment 1

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor