Elasticsearch多语言搜索入门(一)

Elasticsearch自带一套语言分析器(Analyzer),为世界上大多数语言提供良好的支持。Elasticsearch主要支持的语言有:阿拉伯语语、 亚美尼亚语、 巴斯克语、 巴西语、 保加利亚语、 加泰罗尼亚语、 中文、 捷克语、 丹麦语、 荷兰语、 英语、 芬兰语、 法语、 加利西亚语、 德语、 希腊语、 印地语、 匈牙利语、 印尼语、 爱尔兰语、 意大利语、 日语、 韩语、 库尔德语、 挪威语、 波斯语、 葡萄牙语、 罗马尼亚语、 俄语、 西班牙语、 瑞典语、 土耳其语和泰语。

这些语言分析器通常执行下面四个任务:

(1)将文本标记为单个词,如:
    The quick brown foxes → [The, quick, brown, foxes]

    (2)将词变成小写,如:
    The  →  the

   (3) 移除常用停用词,如:
    [The, quick, brown, foxes] → [quick, brown, foxes]
    (4)从切分的词干中获得词根,如:
    foxes → fox

另外,根据某种特定的语言,每个分析器还可以对原始文本进行特定的转换,以便对该语言进行更好的搜索。例如,
(1) 英语分析器可以去掉所有格的形式,如:
    John's → john
   (2)法语分析器可以移除像l'、qu' 、¨或^之类的变音和元音符号,如:
    l'église→eglis
   (3) 德语分析器可以对词(term)进行归一化处理,如将单词中的ä和ae替换为a,将单词中的β替换为ss,如:
    äüßerst→ausserst

下面我们就通过实例看看如何使用语言分析器:

PUT/my_index
{
  "mappings": {
    "blog": {
      "properties": {
        "title": {
          "type":     "string",
          "analyzer":"english"
        }
      }
    }
  }
}

上面的例子就使用了ElasticSearch内置的english分析器在title字段上创建了一个my_index索引,类型为blog。ElasticSearch内置的分析器不需要安装配置,如果要使用IK或MMSeg之类的中文分析器,我们需要安装这些分析器的插件。我们可以使用下面的例子对title上字段上的english语言解析器进行测试:

GET /my_index/_analyze?field=title&text=I'm not happyabout the foxes

运行结果为:

{
  "tokens":[
    {
     "token": "i'm",
     "start_offset": 0,
     "end_offset": 3,
     "type": "<ALPHANUM>",
     "position": 0
    },
    {
     "token": "happi",
     "start_offset": 8,
     "end_offset": 13,
     "type": "<ALPHANUM>",
      "position": 2
    },
    {
     "token": "about",
     "start_offset": 14,
     "end_offset": 19,
     "type": "<ALPHANUM>",
     "position": 3
    },
    {
     "token": "fox",
     "start_offset": 24,
     "end_offset": 29,
     "type": "<ALPHANUM>",
     "position": 5
    }
  ]
}
我们可以看到“I'mnot happy about the foxes”这句话被english分析器拆分为4个词:i'm,happi, about, fox;句子中的not,about和the三个单词是英文中的停用词,没有在被解析出来;而且,happy被解析为其词根happi,foxes被解析为其单数形式fox。通过english分析器解析句子后,我们的搜索会返回更多的结果,不管您输入happiness还是not happy,您都能搜索出这条记录。但是,这样解析之后,缺点是我们损失了原文的一部分信息,我们不能根据索引判断happy还是nothappy。

为了保持原文的精确度,我们可以使用多字段(multifields)进行索引。首先我们使用下面的语句删除my_index,然后使用多字段(multifields)对title字段进行两次索引,一次用english分析器,另一次用standard标准分词器。具体语句如下:

DELETE /my_index
PUT /my_index
{
 "mappings": {
    "blog":{
     "properties": {
       "title": {
         "type": "string",
         "fields": {
           "english": {
             "type":    "string",
              "analyzer": "english"
            }
          }
        }
      }
    }
  }
}

其中,title为主字段,用的是standard标准分词器;而后面的title.english子字段用的是english分析器。创建多字段索引后,我们可以利用下面的语句加载一些测试文本并检索:

PUT /my_index/blog/1
{ "title": "I'm happy for this fox" }
 
PUT /my_index/blog/2
{ "title": "I'm not happy about my fox problem" }
 
GET /_search
{
  "query": {
    "multi_match": {
      "type":     "most_fields", 
      "query":    "not happy foxes",
      "fields": [ "title", "title.english" ]
    }
  }
}
在上面的搜索语句中,我们使用了most_fields关键字对尽可能多的字段进行匹配搜索。搜索结果如下:

{
  "took":109,
 "timed_out": false,
  "_shards":{
    "total": 48,
   "successful": 48,
   "failed": 0
  },
  "hits": {
    "total":2,
   "max_score": 0.10031386,
    "hits":[
      {
       "_index": "my_index",
       "_type": "blog",
       "_id": "2",
       "_score": 0.10031386,
       "_source": {
         "title": "I'm not happy about my fox problem"
        }
      },
      {
       "_index": "my_index",
       "_type": "blog",
       "_id": "1",
       "_score": 0.07141322,
       "_source": {
         "title": "I'm happy for this fox"
        }
      }
    ]
  }
}

我们可以看到,虽然两篇文档都没有含有我们要搜索的foxes,但是由于title字段上的english分析器将foxes转换为fox,所以这两篇文档都能被搜索出来。另外,由于第二篇文档含有我们要检索的单词not,所以第二篇文档的得分score较高,被排在第一篇文档之前。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值