• ElasticSearch 使用小结


    写在前面

    要做个元数据服务,包括存储和查询。元数据除了一些基本字段外,其他格式是自由的,存储输入为一个JSON形式。比如下面是一个文件对象的元数据:

    {
        "name":"myfile",
        "type":"file",
        "user":"ubuntu"
        "path":"node00:/path/to/file"
    }
    

    而下面这个是表示数据表的元数据:

    {
        "name":"mytable",
        "type":"table",
        "user":"ubuntu"
        "location":"node00:mysqldb.table_fake",
        "schema":["name","age","address"]
    }
    

    由于输入格式可变且以JSON形式表示,虽然系统内有类型定义,说明了各个字段的取值类型,但是一些如LIST或者OBJECT之类勉强使用MySQL还是挺累得(需要手动编写代码映射到具体表上的字段)。这从本质上来说JSON对象输入是层次形式的,而关系型数据如MySQL中的数据表式二维平面形式的。

    如果单做key-value存储的话使用MongoDB感觉会非常好,完全的schema free,并且也支持一些基本的查询。但是这个元数据服务还要提供一个搜索功能,通常实现这种搜索功能都是比较烦人的事情,尤其是要支持那些模糊查询。一般来说模糊查询想在大规模数据集上取得比较好的查询效率的话,都是需要建立倒排索引的。这方面MongoDB也是支持的,不过后来使用的ElasticSearch它的查询功能就显的比较弱。其实一开始我是拒绝的,感觉ES就是个做搜索的,相对来说不适合做类似业务存储这类实时性要求比较高的存储。不过它提供的搜索过滤和聚集统计功能真的非常爽,再也不用费尽力去写那些查询组合的SQL了。但在数据存储方面确实比MongoDB烦很多。

    索引层次

    任何查询要提供比暴力搜索好的性能,都需要用到索引,ES当然是不能例外的。而ES中的名称Index和我们所说的索引有些不同,它表示的是一系列字段的索引集合,而不是不是某个字段上的单个索引。因为ES的存储是面向文档的,它的Index意为对文档建立的索引。ES的Index下面可以有不同的Type,对应不同的文档类型。

    数据映射

    不同的文档类型(Type)可以配套的有一个mapping,负责把输入的JSON中的数据映射为指定的类型。这个过程默认是自动进行的。比如输入以下数据

    {"name":"ip-tables", "description":"linux firewall", "version":4}
    

    那么name和description字段自动被判别为字符串类型并会进行分词倒排,而version则是整数类型,可以通过api来查询当前索引的mappings

    $ curl  -XPOST '10.214.208.138:9200/mass/demo' -d'{"name":"ip-tables","description":"linux firewall", "version":4}'
    $ curl  '10.214.208.138:9200/mass/_mappings?pretty'
    {
      "mass" : {
        "mappings" : {
          "demo" : {
            "properties" : {
              "description" : {
                "type" : "string"
              },
              "name" : {
                "type" : "string"
              },
              "version" : {
                "type" : "long"
              }
            }
          }
        }
      }
    }
    
    

    自定义mapping

    除了通过提交json数据可以生成mapping外,还可以人为预先的指定。

    $ curl  -XDELETE '10.214.208.138:9200/mass'
    $ curl  -XPOST '10.214.208.138:9200/mass'
    
    $ curl  -XPUT '10.214.208.138:9200/mass/_mappings/fruit' -d'{"fruit":{"properties":{"name":{"type":"string", "index":"not_analyzed"}}}}'
    
    

    分词控制

    有些字段虽然是文本类型但我们却不想使用分词过程,因为只会进行一些精确查询比如一些枚举字段。可以指定index:not_analyzed

    忽略字段

    其实这个功能我当时找了半天,因为有这样的需求,对JSON字段中的某些元数据只进行存储即可,不需要进行索引和查询。而ES默认会把它看到的所有字段都建立映射,挺烦人的。可以通过配置索引字段的dynamic参数实现,当其为false时忽略那些在已有mapping中没有相应映射规则的字段,不过这个文档还是会被存储到_source字段中,当其为true时会进行自动的类型映射并更新当前的mapping,还可以指定为strict此时如果提交的和预先设定的mapping不一致则拒绝提交。

  • 相关阅读:
    关于相机权限
    JDBC插入中文出现乱码问题
    记一次Java代码的部署
    Java-final关键字
    Java枚举使用详解
    临时表
    Oracle 11g 建表 表名大小写问题
    ORA-04021等待锁定对象时超时
    Oracle 查询时间差几天
    NVL()
  • 原文地址:https://www.cnblogs.com/lailailai/p/4654164.html
Copyright © 2020-2023  润新知