Monday, March 6, 2017

AWS Elasticsearch原理

报纸公司一开始把文章存在数据库的一个叫contents列中,但发现多关键词检索难以做到,即使做到(MySQL的full text search)也比较慢且难以全表搜索(比如把title,tags列也作为搜索目标)。此时,全文搜索应运而生,它可以满足:

1. 全文搜索:多个列中搜索
2. 多关键词:不用写SQL的like一样麻烦
3. 速度更快
4. 高级搜索:比如一次性搜索中,某些关键词权重高些

以下是公司用例:
GitHub:搜索代码和checkin日志
StackOverflow: 搜索问题和答案
HotelTonight:这是结构性数据,有人会有疑问,但它用ES来做多列搜索,如价钱+评分+位置
Wikipedia:搜索文章,用于autocomplete

原理

如ADB课程的proj。首先将文档tokenize,统计每个词(单词规范化,小写过滤)的出现的文档(倒排索引)
data           Doc 1, Doc2
engineer    Doc1
program    Doc2
将这些结果写到多个shard(分片,是实际存储数据的Lucene索引 - DB,含其他某一分片的一个副本,如data存于主片1,当然主片1的副本可含engineer,engineer存于主片2)中,可以保证每个shard做独立搜索,加快速度。然后将结果整合,排序,最后(根据汇总结果)请求原始文档。
更新时候,类似于hashmap,可以找到该词找到相应的shard,更新shard,然后写到文件中,ES会对副本进行异步更新。删除是用soft delete,维护文档版本号,query时候过滤掉旧版本号。

基本概念

ES与MySQL对应概念
MySQL Elasticsearch
Database Index
Table Type
Row Document
Column Field
Schema Mappping
Index Everything Indexed by default
SQL Query DSL

写入数据:
client.index({
    index : 'test',
    type : 'article',
    id : '100',
    body : {
        title : '什么是 JS?',
        slug :'what-is-js',
        tags : ['JS', 'JavaScript', 'TEST'],
        content : 'JS 是 JavaScript 的缩写!',
        update_date : '2015-12-15T13:05:55Z',
    }
})

全文搜索JS:
client.search({
    index : 'test',
    type : 'article',
    q : 'JS',
});

搜索结果:结果都在hits中
























高级搜索DSL(类似于SQL):
1. 只搜某个Document(例如message):match
    "query": {
        "match" : {
            "message" : "this is a test"
        }
    }
2. 准确查找:term
 "query": {
    "term" : { "user" : "Kimchy" }
  }
3. 范围查找:range
"query": {
        "range" : {
            "age" : {
                "gte" : 10,
                "lte" : 20,
                "boost" : 2.0
            }
        }
    }
boost是权重,默认1.0,表示这个query权重较高

AWS

ES由Lucene进化而来,AWS实现了ES从而推出了自己的产品。它的步骤是
1. 创建domain,如叫movies
2. 上传json数据













3. 搜索:全文搜索nightmare
curl -XGET 'search-movies-4oy.us-west-1.es.amazonaws.com/movies/_search?q=nightmare'

AWS例子中,有4步曲,要设为public access以及设置master user名和密码
query的例子:

在某index上搜索
curl -XGET -u 'master-user:master-user-password' 'domain-endpoint/movies/_search?q=mars&pretty=true'

在所有index上搜索
curl -XGET -u 'master-user:master-user-password' 'domain-endpoint/_search?q=mars&pretty=true'

在所有index上搜索多个关键字(类似于或的搜索)
curl -XGET -u 'master-user:master-user-password' 'domain-endpoint/_search?q=mars%20Jack&pretty=true'

在所有index上多域搜索
curl -XGET -u 'master-user:master-user-password' 'domain-endpoint/_search?q=title:mars%20AND%20actors:Jack&pretty=true'

Ref

原理

No comments:

Post a Comment