父文章 

算法中的特征的保存, es 和 mysql 和 odps hadoop hbase的区别_个人渣记录仅为自己搜索用的博客-CSDN博客

Elasticsearch如何做到数十亿数据查询毫秒级响应? - 知乎

ES系列之利用filter让你的查询效率飞起来_es filter_lucasma.eth的博客-CSDN博客

ES查询性能调优实践,亿级数据查询毫秒级返回 - 腾讯云开发者社区-腾讯云

ES的弊端 - 不建议使用. 还是建议 mysql 字段级别的存储. 

1. 不能有动态的key - 例如jsonschema这种 字段名称就是key名的.

 2. list里type不同, 同一个字段类型不同, 无法实现 float或者double.   例如配置一个动态模型,可以配置不同的类型, 和限制值. 如果存到es中会不行.  兜底的方案是schemaParam是jsonStr

以下是 Elasticsearch 的增删改查操作示例:

创建索引


PUT /my_index

{

"settings": { "number_of_shards": 1, "number_of_replicas": 1 },

"mappings": {
        "_doc": {
            "properties": {
                
                "name": {
                    "type": "keyword"
                },
                "age": {
                    "type": "long"
                },
               "birthday": {
                                  "type": "keyword",
                                   "format": "yyyy-MM-dd HH:mm:ss"
                                },
                "desc": {
                    "analyzer": "zsearch_smart",
                    "type": "text"
                },
                 "classList": {
                   "properties": {
                          "className": {
                              "type": "keyword"
                          }
                    }
                  }
              
            }
        }
    },

}

更新索引

PUT mapping_test2/_mapping 
{

"settings": { "number_of_shards": 1, "number_of_replicas": 1 },

"mappings": {
        "_doc": {
            "properties": {

             }

}

ES Mapping设置及常见参数设置 - 简书

ElasticSearch的store属性与_source_elasticsearch store的含义_自知自省的博客-CSDN博客

   当你将一个fieldstore属性设置为true,这个会在lucene层面处理. 在全文索引之外,lucene也提供了存储字段的值的特性,以支持提供id的查询(根据id得到原始信息)。通常我们在lucene层面存储的field的值是跟随search请求一起返回的(id+field的值)。

   从每一个stored field中获取值都需要一次磁盘io,如果想获取多个field的值,就需要多次磁盘io,但是,如果从_source中获取多个field的值,则只需要一次磁盘io,因为_source只是一个整体而已。所以在大多数情况下,从_source中获取是快速而高效的。

   通俗的讲: store 的意思是,是否在 _source 之外在独立存储一份,这里要说一下 _source 这是源文档,当你索引数据的时候, elasticsearch 会保存一份源文档到 _source ,如果文档的某一字段设置了 store 为 yes (默认为 no),这时候会在 _source 存储之外再为这个字段独立进行存储,这么做的目的主要是针对内容比较多的字段,放到 _source 返回的话,因为_source 是把所有字段保存为一份文档,命中后读取只需要一次 IO,包含内容特别多的字段会很占带宽影响性能,通常我们也不需要完整的内容返回(可能只关心摘要),这时候就没必要放到 _source 里一起返回了(当然也可以在查询时指定返回字段)。


————————————————
版权声明:本文为CSDN博主「自知自省」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lijingjingchn/article/details/105682618

详解Elasticsearch中 ‘store‘, ‘index‘ 属性和 ‘_all‘, ‘_source‘字段_elasticsearch中store_梦想画家的博客-CSDN博客

数据类型 - 深度

ES的数据类型_es 数据类型_BUG指挥官的博客-CSDN博客

Elasticsearch索引及字段命名规范_elasticsearch 命名规范_梦想画家的博客-CSDN博客

nested类型和object类型在数组查询中的区别

结果可以看到,当没有显示指定类型是nested时候, 这两组数据都能找出,因为数组虽然每个item都是object, 但是整个数组都是作为一个整体进行搜索匹配, 而非具体某一条数据。

Elasticsearch: object 及 nested 数据类型

Nested 类型是 object 数据类型的特殊版本,它允许对象数组以一种可以彼此独立查询的方式进行索引。在内部,嵌套对象将数组中的每个对象索引为单独的隐藏文档,这意味着每个嵌套对象都可以使用 nested query 独立于其他对象进行查询。每个 nested 对象都被索引为一个单独的 Lucene 文档。nested 数据类型能够让我们对 object 数组建立索引,并且分别进行查询。

如果需要维护数组中每个对象的关系,请使用 nested 数据类型

为了能够把我们的数据定义为nested,我们必须修改之前的索引 mapping 为:
————————————————
版权声明:本文为CSDN博主「Elastic 中国社区官方博客」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/UbuntuTouch/article/details/100068659

  • 如果我们在一个文档中有一个包含 4 个对象的数组,Elasticsearch 在内部将其视为 4 个不同的文档。 因此文档数量会增加,在某些情况下可能会导致计算不准确  from

Elasticsearch:Flattened 数据类型映射_数据映射_Elastic 中国社区官方博客的博客-CSDN博客

Elasticsearch使用误区—索引有上限-误用为key-value数据存储_elasticsearch是key value型数据库吗_梦想画家的博客-CSDN博客

索引字段总量 和 Elasticsearch中flattened字段类型_梦想画家的博客-CSDN博客

对于对象中的子字段默认被单独映射、索引。扁平字段类型是解决字段过多问题的另一种方法,它把整个对象映射未单个字段。给定对象,flattened 类型解析出每个子字段值作为keyword类型,对象中的内容可以通过单个查询进行搜索或聚集。对于唯一字段类型未知的情况非常有用,对于真个json对象仅创建一个映射字段,可以有效防止映射有太多的字段————映射爆炸。

另外扁平对象字段在搜索功能方面提供了一种折衷方案。只允许基本查询,不支持数字范围查询或高亮显示。
————————————————
版权声明:本文为CSDN博主「梦想画家」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/neweastsun/article/details/114290844

ES单字段支持的最大字符数_es字段长度限制_程序媛一枚~的博客-CSDN博客

Elasticsearch:Flattened 数据类型映射_数据映射_Elastic 中国社区官方博客的博客-CSDN博客

Elasticsearch:flattened 数据类型 (7.3 发行版新功能)_flattened elasticsearch_Elastic 中国社区官方博客的博客-CSDN博客

Elasticsearch 字段膨胀不要怕,Flattened 类型解千愁!_铭毅天下的博客-CSDN博客

添加文档



PUT my_index/_doc/xxxxx1/_create { "a":1}

重复插入从插入变成更新, 默认是没有id _create, 否则更新 

{
  "_index" : "my_index",
  "_type" : "_doc",
  "_id" : "xxxxx1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 41,
  "_primary_term" : 1
}

put和post区别

  1. put必须要有id, 否则报错

输入

  PUT fin_resource_allocate_dynamic/_doc/
{
 "a":1
}

输出

{
  "error": "Incorrect HTTP method for uri [/fin_resource_allocate_dynamic/_doc?pretty] and method [PUT], allowed: [POST]",
  "status": 405
}

  2. post 不加_create后缀,每次都是_create [本质原因也是1 ]

 3.   更新操作:post和put 结合id 都有覆盖功能,
              局部更新只有post才有,但需匹配_update 和 {"doc":{}} 才能有

4. _create和post put都可以结合.
1.有id有_create重复执行会报错, 幂等插入
2.有id没有_create重复执行,第一次是create,第二次是更新

错误: 手动加上_create后缀后, _creat变成了id

PUT fin_resource_allocate_dynamic/_doc/_create
{
 "a":1
}

{
  "_index" : "fin_resource_allocate_dynamic",
  "_type" : "_doc",
  "_id" : "_create",
  "_version" : 7,
  "result" : "updated",

  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 49,
  "_primary_term" : 1
}
 

replaceOrInsert

 PUT my_index/_doc/xxxxx1/ 不加后缀,第一次insert 第二次 update

 注意: POST 不加后缀,每次都是insert, 因为没有id

获取文档

ES系列之利用filter让你的查询效率飞起来_es filter_lucasma.eth的博客-CSDN博客

Elasticsearch如何做到数十亿数据查询毫秒级响应? - 知乎

ES查询性能调优实践,亿级数据查询毫秒级返回 - 腾讯云开发者社区-腾讯云

ES中的Query与Filter的区别_MarmotCoder的博客-CSDN博客

[推荐-截图]Elasticsearch 之 Filter 与 Query 有啥不同? - 知乎

id查询没有延迟

GET /my_index/_doc/1

id查询

GET fin_resource_allocate_dynamic/_search

{
  "query": {
    "ids" : {
      "values" : ["com.alipay.fdp.generalZsearchUpdateService"]
    }
  }
}

id搜索query有延迟

GET fin_resource_allocate_dynamic/_search
{ "query": {
    "match": {
       "_id":"ODC6oYcBPebeZ5KFwZ2t"
    }
  }
}

id模糊query搜索,有延迟

GET /my_index/_search

{ "query": { "wildcard": { "_id": "doc*" } } }

在此期间,该文档不能被搜索,但是我们还是可以通过 ID 使用 GET 来获得该文档。如果希望该文档能立刻被搜索,需要手动调用 refresh 操作。在 Elasticsearch 中,默认情况下 _refresh 操作设置为每秒执行一次。 详见 flush、refresh的区别 - 简书

搜索准实时

 延时原理 详见 flush、refresh的区别 - 简书Get API | Elasticsearch Guide [8.6] | Elastic

query下面可挂接 "term""terms","match","multi_match","constant_score","bool" 

"term"在"Term-level queries"目录下, Term query | Elasticsearch Guide [8.7] | Elastic

"match"在" Full text queries"目录下
Match query | Elasticsearch Guide [8.7]

boolean"在" Compound queries"目录下Boolean query | Elasticsearch Guide [8.7] | Elastic

{"query":
   {"bool":{
            "filter":[ {"term":{"_id":{"value":"${docId}"}}}]
         }
   }
}

{ "query": { "term": { "biz_id": "1909190023901225" } }

elasticsearch7常见查询(term、match、bool、filter、match)_bool字段查询 elasticsearch_Relian哈哈的博客-CSDN博客

模糊查询

GET /my_index/_search { "query": { "wildcard": { "orders.items.name": "*Product*" } } }

多层级嵌套数组查询

GET /my_index/_search { "query": {

    "nested": { "path": "orders",

       "query": {

         "nested": { "path": "orders.items", "query": { "wildcard": { "orders.items.name": "*Product*" } } } } } } }

分页查询和优化

深度分页总结

假设我们有一个包含大量文档的 Elasticsearch 索引,我们想要对这些文档进行分页查询。传统的分页查询方式是使用 fromsize 参数来指定要返回的文档范围。但是,这种方式在处理大量文档时可能会变得很慢,因为 Elasticsearch 需要在每次查询时重新计算文档的位置。

为了优化分页查询,我们可以使用上一次查询的最后一项作为下一次查询的起点。这种方式可以避免 Elasticsearch 重新计算文档的位置,从而提高查询性能。

以下是一个使用上一次最后一项进行分页优化的 Elasticsearch 查询示例:

GET /my_index/_search {

"query": { "match_all": {} },

"sort": [ { "created_at": "desc" } ],

"size": 10,

"search_after": [1546300800000] }

在这个查询中,我们使用 sort 参数按照 created_at 字段的降序排列结果。然后,我们使用 size 参数指定每页返回的文档数量为 10。最后,我们使用 search_after 参数指定上一次查询的最后一项,这样 Elasticsearch 就可以使用它作为下一次查询的起点。

使用上一次最后一项进行分页优化可以显著提高 Elasticsearch 查询性能,特别是在处理大量文档时。

注意 es里的文档, key不能是动态生成拼接的, 否则很容易超过index上限, 报错 Limit of total fields [1000] in index [ ] has been exceeded

覆盖

POST fin_resource_allocate_dynamic/_doc/ODC6oYcBPebeZ5KFwZ2t
{    "b":2 }

更新文档局部字段 - 不要忘了 "doc", 否则就是覆盖

本质上 Lucene 不支持部分更新

  请注意,Lucene的部分更新是基于文档级别的,因此您需要在更新文档时提供完整的文档内容。如果您只想更新文档的部分内容,您需要在更新前获取完整的文档内容,并将要更新的字段合并到新文档中。

 所以大文档的更新对es , 性能不是特别好

POST fin_resource_allocate_dynamic/_doc/ODC6oYcBPebeZ5KFwZ2t/_update
{ "doc":{    "b":2} }

如果结构变更, 那么会抛错. 数组-String不会.

"field_not_config" : "1", -> "field_not_config" : ["1"],

"field_not_config" : "1", -> "field_not_config" : [1],  字符串变数字 ,可以, 进行了 封包,拆装. 更新允许,但不建议.

但是 "field_not_config" : "1", -> "field_not_config" : {"key": "1"}

但是String变map会. 数组不是类型.

    host [http://xx.x.net:12345], URI [/inst_xxx_test/_doc/antc.fin.allocate-v1-PLATFORM-FIN_RES_ALLOCATE-outRequestNo/_update], status line [HTTP/1.1 400 Bad Request]
通过    GET inst_xxx_test/_mapping 可以知道  


      #! Deprecation: 299 Elasticsearch-6.8.6-4268ecc "[types removal] The parameter include_type_name should be explicitly specified in get mapping requests to prepare for 7.0. In 7.0 include_type_name will default to 'false', which means responses will omit the type name in mapping definitions."
{
  "inst_xxx_test" : {
    "mappings" : {
      "_doc" : {
        "_all" : {
          "enabled" : false
        },
        "dynamic_templates" : [
          {
            "strings" : {
              "match_mapping_type" : "string",
              "mapping" : {
                "type" : "keyword"
              }
            }
          }
        ],
        "properties" : {
          "field_not_config" : {
            "type" : "keyword"
          }
         
        }
      }
    }
  }
}

 报错_update放中间

POST my_index/_update/ODC6oYcBPebeZ5KFwZ2t

{
  "error": {
    "root_cause": [
      {
        "type": "invalid_type_name_exception",
        "reason": "Document mapping type name can't start with '_', found: [_update]"
      }
    ],
    "type": "invalid_type_name_exception",
    "reason": "Document mapping type name can't start with '_', found: [_update]"
  },
  "status": 400
}

 POST /my_index/_update/1 { "doc": { "title": "Elasticsearch 101 - Updated" } } 

报错: update 放中间

POST my_index/update/ODC6oYcBPebeZ5KFwZ2t

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "Rejecting mapping update to [my_index] as the final mapping would have more than 1 type: [_doc, update]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "Rejecting mapping update to [my_index] as the final mapping would have more than 1 type: [_doc, update]"
  },
  "status": 400
}

报错: _update后缀,但内容里没有"doc"


POST fin_resource_allocate_dynamic/_doc/ODC6oYcBPebeZ5KFwZ2t/_update
{
  "b":3,
  "c":6

}

{
  "error": {
    "root_cause": [
      {
        "type": "action_request_validation_exception",
        "reason": "Validation Failed: 1: script or doc is missing;"
      }
    ],
    "type": "action_request_validation_exception",
    "reason": "Validation Failed: 1: script or doc is missing;"
  },
  "status": 400
}

报错: 不支持post 加_update后缀

put fin_resource_allocate_dynamic/_doc/ODC6oYcBPebeZ5KFwZ2t/_update
{
    "b":4
}

{
  "error": {
    "type": "illegal_argument_exception",
    "reason": "No endpoint or operation is available at [PUT /fin_resource_allocate_dynamic/_doc/ODC6oYcBPebeZ5KFwZ2t/_update?pretty]"
  },
  "status": 400
}

删除文档


DELETE /my_index/_doc/1

搜索文档


GET /my_index/_search { "query": { "match": { "title": "Elasticsearch" } } }

以上操作的结果可以通过 Elasticsearch 的 API 返回,例如:


{ "_index": "my_index", "_type": "_doc", "_id": "1", "_version": 2, "result": "updated", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 1, "_primary_term": 1 }

这个结果表示文档已经被更新,并且版本号从 1 变成了 2。

数组更新

Elasticsearch中的一个文档可以包含多个嵌套的字段和数组。当需要修改一个数组文档时,可以使用以下两种方法:

  1. 部分更新:

部分文档更新可以使用Update API执行,通过提交包含仅需要包含要更新字段的JSON数据块,进行更新。在JSON数据中指定当前数组项,例如,要更新数组items的第二个项目:

POST /myindex/mytype/1/_update { "doc": { "items.2": "new value" } }

这将替换第二项为新值,不需要重写拥有不变值的所有内容。

  1. 全部更新:

如果需要直接替换原有的整个数组,可以使用index API执行全文档的更新,此时新文档必须包含或重新定义完整的嵌套结构

PUT my_index/my_type/1?refresh=true
{
    "name":    "John Doe",
    "age":    33,
    "items": [ "beijing”, “shanghan”, ”shenzhen”]
}

在上例中,原有的items字段被替换成新的值。

数组添加

下面是一个示例,在Elasticsearch中创建一个文档mydoc,其中items是数组字段:


PUT /myindex/mytype/1 { "items": ["apple", "banana", "peach"] }

现在,我们可以通过查询该文档来展示原始文档:


GET /myindex/mytype/1

items数组添加一个新元素orange

POST /myindex/mytype/1/_update { "script": { "source": "ctx._source.items.add(params.newitem)", "params": { "newitem": "orange" } } }

同样,我们可以用GET请求来显示文档:

GET /myindex/mytype/1

此时获取到的文档会包含orange这个新加的元素。

数组查询

nested类型和object类型在数组查询中的区别

结果可以看到,当没有显示指定类型是nested时候, 这两组数据都能找出,因为数组虽然每个item都是object, 但是整个数组都是作为一个整体进行搜索匹配, 而非具体某一条数据。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐