• Elasticsearch创建索引和映射结构详解


    前言

    这篇文章详细介绍了如何创建索引和某个类型的映射。

    下文中[address]指代elasticsearch服务器访问地址(http://localhost:9200)。

    1       创建索引

    1.1     简单创建语句

    curl -XPUT [address]/blog

    1.2     带参数的创建语句

    curl -XPUT [address]/blog/ -d '{

        "settings":{

               "number_of_shards":1,     //设置分片数量

               "number_of_replicas":2,  //设置副本数量

               //自定义索引默认分析器

               "index":{

                      "analysis":{

                             "analyzer":{

                                    "default":{

                                           "tokenizer":"standard",     //分词器

                                           "filter":[ //过滤器

                                                  "asciifolding",

                                                  "lowercase",

                                                  "ourEnglishFilter"

                                           ]

                                    }

                             },

                             "filter":{

                                    "ourEnglishFilter":{

                                           "type":"kstem"

                                    }

                             }

                      }

               }

        }

    }'

    2       创建映射(扁平结构)

    2.1     简单创建语句

    curl -XPUT [address]/blog/_mapping/article?pretty -d '{

             "properties":{

                       "id":{"type":"long"},

                       "name":{"type":"string"},

                       "published":{"type":"date"}

             }

    }'

    2.2     带参数的创建语句

    curl -XPUT [address]/blog/_mapping/article?pretty -d '{

             "dynamic":"false",  //关闭自动添加字段,关闭后索引数据中如果有多余字段不会修改mapping,默认true

             "_id":{"index":"not_analyzed","store":"no"},        //设置文档标识符可以被索引,默认不能被索引。可以设置为"_id":{"path":"book_id"},这样将使用字段book_id作为标识符

             "_all":{"enabled":"false"},       //禁用_all字段,_all字段包含了索引中所有其他字段的所有数据,便于搜索。默认启用

             "_source":{"enabled":"false"},        //禁用_source字段,_source字段在生成索引过程中存储发送到elasticsearch的原始json文档。elasticsearch部分功能依赖此字段(如局部更新功能),因此建议开启。默认启用

             "_index":{"enabled":"true"},  //启用_index字段,index字段返回文档所在的索引名称。默认关闭。

             "_timestamp":{"enabled":"true","index":"not_analyzed","store":"true","format":"YYYY-mm-dd"},                  //启用时间戳并设置。时间戳记录文档索引时间,使用局部文档更新功能时,时间戳也会被更新。默认未经分析编入索引但不保存。

             "_ttl":{"enabled":"true","default":"30d"},     //定义文档的生命周期,周期结束后文档会自动删除。

             "_routing":{"required":"true","path":"name"}      //指定将name字段作为路由,且每个文档必须指定name字段。

            

             "properties":{

                       "id":{

                                "type":"long",

                               

                                //公共属性

                                "store":"yes",

                               

                                //数值特有属性

                                "precision_step":"0"       //指定为该字段生成的词条数,值越低,产生的词条数越多,查询会更快,但索引会更大。默认4

                               

                       },

                       "name":{

                                "type":"string",

                               

                                //公共属性

                                "store":"yes",

                                "index":"not_analyzed", //analyzed:编入索引供搜索、no:不编入索引、not_analyzed(string专有):不经分析编入索引

                                "boost":"1",    //文档中该字段的重要性,值越大表示越重要,默认1

                                "null_value":"jim",  //当索引文档的此字段为空时填充的默认值,默认忽略该字段

                                "include_in_all":"xxx"      //此属性是否包含在_all字段中,默认为包含

                               

                                //字符串特有属性

                                "analyzer":"xxx",     //定义用于索引和搜索的分析器名称,默认为全局定义的分析器名称。可以开箱即用的分析器:standard,simple,whitespace,stop,keyword,pattern,language,snowball

                                "index_analyzer":"xxx",           //定义用于建立索引的分析器名称

                                "search_analyzer":"xxx",        //定义用于搜索时分析该字段的分析器名称

                                "ignore_above":"xxx"      //定义字段中字符的最大值,字段的长度高于指定值时,分析器会将其忽略

                               

                               

                       },

                       "published":{

                                "type":"date",

                               

                                //公共属性

                                "store":"yes",

                               

                                //日期特有属性

                                "precision_step":"0",      //指定为该字段生成的词条数,值越低,产生的词条数越多,查询会更快,但索引会更大。默认4

                                "format":"YYYY-mm-dd"          //指定日期格式,默认为dateOptionalTime

                       }

             }

    }'

     

    3       创建映射(非扁平结构)

    在第二章我们讲解了创建映射的语句。所创建的是简单的扁平结构映射。这一章我们看看如何创建非扁平结构映射。

    3.1     树形结构

    树形结构的作用是为索引层级路径提供便利。例如一家汽车店中可能会有如下路径:/cars/passenger/sport、/cars/passenger/camper、/cars/delivery_truck,我们想在搜索cars的时候返回三条记录,搜索cars/passenger的时候返回前两条记录,可以这样建立映射:

    curl -XPUT [address]/path -d '{

             "settings":{

                       //定义一个路径分析器

                       "index":{

                                "analysis":{

                                         "analyzer":{

                                                   "path_analyzer":{"tokenizer":"path_hierarchy"}

                                         }

                                }

                       }

             },

             "mappings":{

                       "category":{

                                "properties":{

                                         "category":{

                                                   "type":"string",

                                                   "fields":{

                                                            //定义多字段对象,使用category.path进行查询时将启用路径分析匹配指定路径下的所有文档,使用category.name进行查询时将精确匹配指定路径的文档,略过结构更深的文档。

                                                            "name":{"type":"string","index":"not_analyzed"},

                                                            "path":{"type":"string","analyzer":"path_analyzer","store":true}

                                                   }

                                         }

                                }

                       }

             }

    }'

     

    3.2     对象

    先执行curl –XPUT [address]/extend_mapping,创建extend_mapping索引

    创建一个带有对象属性author的类型book:

    curl –XPUT [address]/extend_mapping/_mapping/book –d ‘{

             "properties":{

                       "title":{"type":"string","index":"not_analyzed"},

                       "author":{

                                "type":"object",

                                "properties":{

                                         "firstName":{"type":"string","index":"not_analyzed"},

                                         "lastName":{"type":"string","index":"not_analyzed"}

                                }

                      

                       }

             }

    }’

    3.3     嵌套对象

    嵌套对象允许我们连接一个主文档和多个附属文档,下面通过一个例子来说明嵌套对象的应用场景。

    现在我们有一个服装店,需要设计一个数据结构来存储服装店里的服装信息。例如现在有一种名字为”cloth”的服装,这件服装现有两件存货,一件XXL的红色和一件XL的黑色,请设计一个数据结构来存储该服装信息。

    我们可能会把数据结构设计成这样:

    {

             “name”:”cloth”,

             “variation”:[

                       {“size”:”XXL”,”color”:”red”},

                       {“size”:”XL”,”color”:”black”}

    ]

    }

    直观的来看,这个数据结构是能够表现我们所描述的服装信息的,我们依据这个结构创建以下映射(发送rest请求语句略):

     

    {

    "properties":{

             "name":{"type":"string","index":"not_analyzed"},

             "variation":{

                       "properties":{

                                "size":{"type":"string","index":"not_analyzed"},

                                "color":{"type":"string","index":"not_analyzed"}

                       }

             }

    }

    }

    建立映射后索引以下数据:

    {

        "name": "cloth",

        "variation": [

            {

                "size": "XXL",

                "color": "red"

            },

            {

                "size": "XL",

                "color": "black"

            }

        ]

    }

    下面我们查询一下我们的服装信息库,看看是否有尺寸为XXL,颜色为black的服装:

    {

      "filter": {

        "and": [

          {

            "term": {

              "variation.size": "XXL"

            }

          },

          {

            "term": {

              "variation.color": "black"

            }

          }

        ]

      }

    }

             出乎意料的是,该查询返回了结果:

    {

             ......(此处信息略去)

        "hits": {

            "total": 1,

            "max_score": 1,

            "hits": [

                {

                    "_index": "extend_mapping",

                    "_type": "unnested_cloth",

                    "_id": "AVACnlA-8eAUpvGq_eZa",

                    "_score": 1,

                    "_source": {

                        "name": "cloth",

                        "variation": [

                            {

                                "size": "XXL",

                                "color": "red"

                            },

                            {

                                "size": "XL",

                                "color": "black"

                            }

                        ]

                    }

                }

            ]

        }

    }

    这与我们的预期不符,我们只有XXL红色和XL黑色两件服装,并没有所查询的XXL黑色服装。

    这是因为按照我们之前定义的映射结构,尺寸信息(“size”:”XXL”,”size”:”XL”)和颜色信息(“color”:”red”,”color”:”black”)都存在同一个文档中,ES无法将XXL和red、XL和black绑定在一起,因此在查询时造成了混淆。

    解决的方法就是使用嵌套对象,将variation对象的类型指定为嵌套:

    重新创建以下映射:

    {

    "properties":{

             "name":{"type":"string","index":"not_analyzed"},

             "variation":{

                       “type”:”nested”,

                       "properties":{

                                "size":{"type":"string","index":"not_analyzed"},

                                "color":{"type":"string","index":"not_analyzed"}

                       }

             }

    }

    }

    索引之前的测试数据:

    {

        "name": "cloth",

        "variation": [

            {

                "size": "XXL",

                "color": "red"

            },

            {

                "size": "XL",

                "color": "black"

            }

        ]

    }

    现在我们通过”type”:”nested”将variation对象指定为嵌套对象,需要注意的是,如果我们对新映射执行类似之前的查询,将无任何文档返回。因为对于嵌套映射,必须要使用专用的查询语法,如下:

    {

        "filter": {

            "nested": {

                "path": "variation",

                "filter": {

                    "and": [

                        {

                            "term": {

                                "variation.size": "XXL"

                            }

                        },

                        {

                            "term": {

                                "variation.color": "black"

                            }

                        }

                    ]

                }

            }

        }

    }

             这次的查询如我们的预期,没有返回结果。这是因为使用嵌套结构后,当我们索引测试数据时,事实上ES生成了3个文档,一个cloth的主文档,和两个variation对象的附属文档,这样就分离存储了两件服装存货,避免了尺寸和颜色的混淆。

  • 相关阅读:
    Oracle 不同故障的恢复方案
    IBM HACMP 系列 后期安装工作和管理任务二
    How to map SCN with Timestamp before 10g [ID 365536.1]
    ORA02024: Database Link Not Found [ID 1058949.1]
    IBM HACMP 系列 后期安装工作和管理任务三
    IBM System p5 服务器 HACMP 安装指南
    Oracle 不同用户之间 大量数据转移的方法测试
    Oracle 不同故障的恢复方案
    Nocatalog 下的RMAN 增量备份 shell脚本
    IBM HACMP 系列 安装和配置二
  • 原文地址:https://www.cnblogs.com/sheeva/p/4837881.html
Copyright © 2020-2023  润新知