V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
CodingNET
V2EX  ›  Elasticsearch

5 分钟内学会使用搜索利器 Elastic Search

  •  2
     
  •   CodingNET · 2015-08-19 10:56:05 +08:00 · 7288 次点击
    这是一个创建于 3368 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本文简要介绍搜索利器 Elastic Search ,让你在 5 分钟内学会使用它。

    安装

    如果你有 linux ,并且恰好也有 docker , 那么请运行如下命令:

    sudo docker run -d -p 9200:9200 -p 9300:9300 elasticsearch
    

    你要是看到一串 id , 恭喜你, 你已经有了自己的搜索了!就是这么简单!

    我们来验证一下搜索服务:

    ubuntu:~$ curl localhost:9200
         {
           "status" : 200,
           "name" : "Adonis",
           "cluster_name" : "elasticsearch",
           "version" : {
             "number" : "1.7.1",
             "build_hash" : "b88f43fc40b0bcd7f173a1f9ee2e97816de80b19",
             "build_timestamp" : "2015-07-29T09:54:16Z",
             "build_snapshot" : false,
             "lucene_version" : "4.10.4"
           },
           "tagline" : "You Know, for Search"
         }
    

    返回值 200 !你成功了!这个结果除了告诉你 Elastic Search 已经启动好之外,还显示了版本号, build 信息, lucene 版本等信息。

    如果你不用 Linux 或者 Docker ,放心,情况也不复杂。首先你需要 Java ,然后去官网下载,解压,运行既可。

    使用

    Elastic Search 的初级功能十分易用。 Restful 请求就可以完成一切操作。所以接下来的体验,你只需要一个命令行即可,但是为了直观方便,你也可以选择官方推荐的 Marvel 或者 Postman

    相信很多人都是吃货,下面,我用中国第九大菜系食堂菜作为搜索的原数据演示 Elastic Search 的用法。

    插入数据

    首先来一道勉强正常的菜,苹果炖牛肉。

    ubuntu:~$ curl -XPOST localhost:9200/food/canteen?pretty -d '{title: "苹果炖牛肉", source: "sjtu"}'
          {
           "_index" : "food",
           "_type" : "canteen",
           "_id" : "AU8HEQxfW68mQc8rk4AS",
           "_version" : 1,
           "created" : true
         }
    

    有点迷糊?那来稍微介绍一点背景知识,看看上面的命令都做了啥。

    Elastic Search 使用 document 方式存储, 类似 MongoDB 。它不仅高效而且分布式扩展性极佳,基于赫赫有名的 Lucene 搭建,在搜索界的地位就如同杰伦小公举在歌坛的地位一般。很多人可能有关系型数据库开发的经验,下面来张 Elastic Search 和 MySQL 的术语类比图,帮助理解。

    MySQL Elastic Search
    Database Index
    Table Type
    Row Document
    Column Field
    Schema Mappping
    Index Everything Indexed by default
    SQL Query DSL

    上面例子中,localhost:9200是服务地址, Elastic Search 默认利用 9200 作为 Rest 服务的端口, 9300 作为内部通信接口和 Java 客户端接口。food是 index ,canteen是 type ,里面的数据形成 document 。值得注意的是,跟其他 NoSQL 数据库一样, Schema 不需要预先定义,直接插入数据即可, Elastic Search 会智能地分析每个 Field 的值并自动建立索引。每个 document 都有一个 id ,如果不指定则会自动生成。可以看到插入成功之后,生成了"_id" : "AU8HEQxfW68mQc8rk4AS"。插入命令使用 Post 请求,方便使用和测试。

    另外,在上面的例子中,我加入了?pretty主要是让结果的 json 显示更好看。

    获取数据

    虽然数据已经存好了,但是没有直接取到,总是心有不安,下面这条命令即可以查看数据:

    ubuntu:~$ curl -XGET localhost:9200/food/canteen/AU8HEQxfW68mQc8rk4AS?pretty
    {
      "_index" : "food",
      "_type" : "canteen",
      "_id" : "AU8HEQxfW68mQc8rk4AS",
      "_version" : 1,
      "found" : true,
      "_source":{title: "苹果炖牛肉", source: "sjtu"}
    }
    

    可以看到,请求改为了GET,请求形式为/index/type/id

    更新数据

    再来一道菜,番茄炒菠萝,用到我们刚才说的POST请求。

    ubuntu:~$ curl -XPOST localhost:9200/food/canteen?pretty -d '{title: "番茄炒菠萝", source: "sjtu"}'
         {
           "_index" : "food",
           "_type" : "canteen",
           "_id" : "AU8HQW0-W68mQc8rk4Ab",
           "_version" : 1,
           "created" : true
         }
    

    等等,这道菜是武汉大学的,看来我们得更新一下source。也许聪明的你已经猜到,发个PUT请求就可以搞定了。

    ubuntu:~$ curl -XPUT localhost:9200/food/canteen/AU8HQW0-W68mQc8rk4Ab?pretty -d '{title: "番茄炒菠萝", source: "whu"}'
         {
           "_index" : "food",
           "_type" : "canteen",
           "_id" : "AU8HQW0-W68mQc8rk4Ab",
           "_version" : 2,
           "created" : false
    }
    

    可以看到_version变成了 2 ,表示更新过了。再GET一下确认结果。

    ubuntu:~$ curl -XGET localhost:9200/food/canteen/AU8HQW0-W68mQc8rk4Ab?pretty
         {
           "_index" : "food",
           "_type" : "canteen",
           "_id" : "AU8HQW0-W68mQc8rk4Ab",
           "_version" : 2,
           "found" : true,
           "_source":{title: "番茄炒菠萝", source: "whu"}
         }
    

    可以看到,_source,也就是插入的原始数据,确实改变了。

    删除数据

    继续来一道菜,月饼炒辣椒!

    ubuntu:~$ curl -XPOST localhost:9200/food/canteen?pretty -d '{title: "月饼炒辣椒", source: "fjnu"}'
         {
           "_index" : "food",
           "_type" : "canteen",
           "_id" : "AU8HRPoOW68mQc8rk4Ac",
           "_version" : 1,
           "created" : true
         }
    

    算了,好像太丧心病狂了,对吃货的幼小心灵产生了暴击,我们还是把它删掉吧。

    ubuntu:~$ curl -XDELETE localhost:9200/food/canteen/AU8HRPoOW68mQc8rk4Ac?pretty
         {
           "found" : true,
           "_index" : "food",
           "_type" : "canteen",
           "_id" : "AU8HRPoOW68mQc8rk4Ac",
           "_version" : 2
         }
    

    GET验证一下是否真的被删除了。

    ubuntu:~$ curl -XGET localhost:9200/food/canteen/AU8HRPoOW68mQc8rk4Ac?pretty
         {
           "_index" : "food",
           "_type" : "canteen",
           "_id" : "AU8HRPoOW68mQc8rk4Ac",
           "found" : false
         }
    

    显示"found" : false,可见删除确实成功了。

    搜索数据

    Elastic Search 支持相当复杂的搜索情形。像“有水果有肉有主食红黄白相间成粒状”这种可以把 MySQL 的检索虐得死去活来的查询, Elastic Search 可以轻松告诉你这应该是名菜“哈密瓜年糕牛肉粒”。下面看看最简单却很实用的搜索:查询所有值。

    ubuntu:~$ curl -XGET localhost:9200/food/canteen/_search?pretty
         {
           "took" : 1,
            "timed_out" : false,
            "_shards" : {
              "total" : 5,
              "successful" : 5,
              "failed" : 0
            },
            "hits" : {
              "total" : 2,
             "max_score" : 1.0,
              "hits" : [ {
               "_index" : "food",
               "_type" : "canteen",
               "_id" : "AU8HEQxfW68mQc8rk4AS",
               "_score" : 1.0,
               "_source":{title: "苹果炖牛肉", source: "sjtu"}
             }, {
               "_index" : "food",
               "_type" : "canteen",
               "_id" : "AU8HQW0-W68mQc8rk4Ab",
               "_score" : 1.0,
               "_source":{title: "番茄炒菠萝", source: "whu"}
             } ]
           }
         }
    

    可以看到,形如GET _search即可。结果会显示所有给定 index 和 type 下的 document 。hits下面包含找到的具体内容。_score表示相关程度,分数越高表示越相关,搜索引擎对于结果的排序都是通过类似的机制完成。
    再来一个简单地查询,查找sourcesjtu的菜。

    ubuntu:~$ curl -XGET localhost:9200/food/canteen/_search?pretty -d '{"query":{"match":{"source":"sjtu"}}}'
         {
           "took" : 35,
           "timed_out" : false,
           "_shards" : {
             "total" : 5,
             "successful" : 5,
             "failed" : 0
           },
           "hits" : {
             "total" : 1,
             "max_score" : 0.30685282,
             "hits" : [ {
               "_index" : "food",
               "_type" : "canteen",
               "_id" : "AU8HEQxfW68mQc8rk4AS",
               "_score" : 0.30685282,
               "_source":{title: "苹果炖牛肉", source: "sjtu"}
             } ]
           }
         }
    

    这里用到了match query来搜索,可以看到_score的变化。

    结语

    本文对 Elastic Search 的使用作了最简单的介绍,适合新手入门。上述例子简单直观,命令可以直接运行,亲测有效。有兴趣的读者可以自己动手实践,加入更多诸如“糖宝炖骨头”这样的黑暗料理。

    全文: https://blog.coding.net/blog/elastic-search

    PS :

    Coding 在 V2EX 的 Social Integration 已上线,小伙伴们可以在 https://www.v2ex.com/settings 添加自己的 Coding 地址啦!
    效果见: https://www.v2ex.com/member/CodingNET

    20 条回复    2015-08-20 11:11:58 +08:00
    qinglangee
        1
    qinglangee  
       2015-08-19 11:05:38 +08:00
    Elastic Search 是什么
    andy12530
        2
    andy12530  
       2015-08-19 11:24:57 +08:00
    ES 的 query 串写起来,太费劲了
    wbsdty331
        3
    wbsdty331  
       2015-08-19 11:27:24 +08:00
    苹果炖牛肉笑飞
    tabris17
        4
    tabris17  
       2015-08-19 11:28:02 +08:00
    mapping 都没讲啊,这个离实战还差一点
    zkd8907
        5
    zkd8907  
       2015-08-19 15:45:04 +08:00
    苹果炖牛肉是什么鬼。。
    EPr2hh6LADQWqRVH
        6
    EPr2hh6LADQWqRVH  
       2015-08-19 15:49:49 +08:00
    无视中文分词啊,这都行,真把这当软文了啊,不要为了写而写啊
    lijinma
        7
    lijinma  
       2015-08-19 16:07:26 +08:00
    哈哈,我觉得最基本的为什么使用 ES 都没讲,这才是最重要的。

    另外,中文 ik 分词啥的得提一提
    RIcter
        8
    RIcter  
       2015-08-19 17:38:09 +08:00 via iPhone
    ES 自帶的 HQ 插件很好用,完全不用操心。
    simodorg
        9
    simodorg  
       2015-08-19 17:58:10 +08:00 via iPhone
    好奇在这里除了他自己还有谁加了 coding 的账号...
    yakczh
        10
    yakczh  
       2015-08-19 18:00:29 +08:00
    跟 solr 相比,内存占用怎么样?
    tolbkni
        11
    tolbkni  
       2015-08-19 20:58:23 +08:00
    ES 的组合查询门槛有点高,不停翻文档才搞定
    cnZary
        12
    cnZary  
       2015-08-19 21:06:52 +08:00 via Android
    番茄炒菠萝好吃?
    anubiskong
        13
    anubiskong  
       2015-08-19 21:44:51 +08:00
    coding.net 写东西就这个水平吗?
    df4VW
        14
    df4VW  
       2015-08-20 00:24:50 +08:00
    @andy12530 现在已经好多了吧。。以前
    49
        15
    49  
       2015-08-20 07:35:32 +08:00 via Android
    @RIcter RR 都这么说了…那我肯定要去试试
    FastWood
        16
    FastWood  
       2015-08-20 08:16:16 +08:00
    感谢
    li24361
        17
    li24361  
       2015-08-20 09:03:57 +08:00
    很早就关注 es 了,用来替代 Lucene , but , es 的服务器要求 12G 以上内存,当时就吓软了
    lZl
        18
    lZl  
       2015-08-20 09:06:12 +08:00
    ES 也是用 Lucene ,替代也是替代 Solr 。。。
    nullcc
        19
    nullcc  
       2015-08-20 10:51:45 +08:00
    es 算是开源的全文搜索引擎里面比较容易入门的了,不过对内存要求太高
    master13
        20
    master13  
       2015-08-20 11:11:58 +08:00
    用 RESTful API 能实现搜索的功能。一般还需要一个“套”,让他好看一点—— boss 不会喜欢看 JSON 数据的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3555 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 10:38 · PVG 18:38 · LAX 02:38 · JFK 05:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.