ElasticSearch检索你的数据(四)

本文详细介绍了Elasticsearch中检索选定字段的方法,包括使用`fields`选项获取映射字段值,检索嵌套字段,以及如何处理未映射字段。此外,还阐述了跨集群搜索的功能,如设置远程集群,执行搜索,以及如何在网络延迟环境下优化性能。内容涵盖了搜索指定字段,响应格式,以及如何处理嵌套和未映射字段的细节。
摘要由CSDN通过智能技术生成

ElasticSearch检索你的数据(四)

检索选中的字段

默认情况下每一个搜索的响应的hit都包含文档的_source字段,它是索引文档时提供的整个 JSON 对象。有两种推荐方法从搜索查询中检索选中字段“

  • 使用fields option提取索引映射中存在的字段值
  • 使用_source option来访问元数据

你可以同时使用这两种方法,但首选 fields option,因为它会同时查询文档数据和索引映射。在其他例子中,你可能使用其他的方式来检索数据。

filed option

使用fileds参数在查询的响应中检索指定的字段。因为它参考索引映射,所以 fields 参数比直接引用 _source 有几个优点。具体来说,fields参数:

  • 通过匹配映射类型的标准方式返回每一个值
  • 接收multi-filedsfield alias
  • 格式化时间与空间数据类型
  • 检索运行时字段
  • 在索引时可以通过脚本计算字段值并返回

其他映射选项也被考虑,包括ignore_aboveignore_malformednull_value

fields选项以Elasticsearch索引相匹配的方式返回值。对于标准的字段,这就意味着field选项会在_source字段中查找值,然后使用映射来解析与格式化他们。

搜索指定的字段

以下搜索请求使用 fields 参数检索 user.id 字段、所有以 http.response. 开头的字段和 @timestamp 字段的值。

用对象表示法,您可以为某些字段传递格式参数,以便为字段值应用自定义格式:

  • datedate_nanos字段接收date_format
  • Spatial fields accept either geojson for GeoJSON (the default) or wkt for Well Known Text

其他字段不支持格式化参数:

curl -X POST "localhost:9200/my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "user.id": "kimchy"
    }
  },
  "fields": [
    "user.id",
    "http.response.*",         
    {
      "field": "@timestamp",
      "format": "epoch_millis" 
    }
  ],
  "_source": false
}
'

响应总是返回一个数组

fields响应总是为每个字段返回值数组,尽管只有在_source中只有一个单独的值。这是因为ElasticSearch没有专门的数据类型,并且任何字段可以包含多个值。fields 参数也不保证以特定顺序返回数组值。有关更多背景信息,请参阅有关数组的映射文档。

响应中每个hit的fields部分都包含值的列表。因为field参数不会拉取全文对象,只有叶子字段会被返回:

{
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my-index-000001",
        "_id" : "0",
        "_score" : 1.0,
        "_type" : "_doc",
        "fields" : {
          "user.id" : [
            "kimchy"
          ],
          "@timestamp" : [
            "4098435132000"
          ],
          "http.response.bytes": [
            1070000
          ],
          "http.response.status_code": [
            200
          ]
        }
      }
    ]
  }
}

检索嵌套字段

嵌套字段的字段响应与常规的字段响应是不同的。虽然常规对象字段内的叶值作为平面列表返回,但嵌套字段内的值被分组以保持原始嵌套数组内每个对象的独立性。对于嵌套字段数组中的每个条目,值将再次作为平面列表返回,除非父嵌套对象中有其他嵌套字段,在这种情况下,对更深的嵌套字段再次重复相同的过程。

给定以下映射,其中user是一个嵌套字段,索引以下文档并检索用户字段下的所有字段:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "group" : { "type" : "keyword" },
      "user": {
        "type": "nested",
        "properties": {
          "first" : { "type" : "keyword" },
          "last" : { "type" : "keyword" }
        }
      }
    }
  }
}
'
curl -X PUT "localhost:9200/my-index-000001/_doc/1?refresh=true&pretty" -H 'Content-Type: application/json' -d'
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
'
curl -X POST "localhost:9200/my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "fields": ["*"],
  "_source": false
}
'

响应会将名字和姓氏分组,而不是将它们作为平面列表返回。

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [{
      "_index": "my-index-000001",
      "_id": "1",
      "_score": 1.0,
      "_type": "_doc",
      "fields": {
        "group" : ["fans"],
        "user": [{
            "first": ["John"],
            "last": ["Smith"],
          },
          {
            "first": ["Alice"],
            "last": ["White"],
          }
        ]
      }
    }]
  }
}

无论用于检索它们的模式如何,嵌套字段都将按其嵌套路径分组。例如,如果您只查询上一个示例中的 user.first 字段:

curl -X POST "localhost:9200/my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "fields": ["user.first"],
  "_source": false
}
'

响应仅返回用户的名字,但仍保持嵌套用户数组的结构:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [{
      "_index": "my-index-000001",
      "_id": "1",
      "_score": 1.0,
      "_type": "_doc",
      "fields": {
        "user": [{
            "first": ["John"],
          },
          {
            "first": ["Alice"],
          }
        ]
      }
    }]
  }

提取未映射的字段

默认情况下,fields参数只返回别映射的字段的值。但是,ElasticSearch允许在_source中存储未映射的字段,例如设置dynamic field mappingfalse或者使用带有enabled:false的字段。.这些选项禁用对象内容的解析和索引。

_source字段中检索一个对象中未映射的字段,在field部分中使用include_ummapped选项:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "enabled": false 
  }
}
'
curl -X PUT "localhost:9200/my-index-000001/_doc/1?refresh=true&pretty" -H 'Content-Type: application/json' -d'
{
  "user_id": "kimchy",
  "session_data": {
     "object": {
       "some_field": "some_value"
     }
   }
}
'
curl -X POST "localhost:9200/my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "fields": [
    "user_id",
    {
      "field": "session_data.object.*",
      "include_unmapped" : true 
    }
  ],
  "_source": false
}
'

响应将包含 session_data.object.* 路径下的字段结果,即使这些字段未映射。 user_id 字段也未映射,但不会包含在响应中,因为该字段模式的 include_unmapped 未设置为 true。

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my-index-000001",
        "_id" : "1",
        "_score" : 1.0,
        "_type" : "_doc",
        "fields" : {
          "session_data.object.some_field": [
            "some_value"
          ]
        }
      }
    ]
  }
}

_source选项

您可以使用 _source 参数来选择返回源的哪些字段。这称为源过滤。

以下搜索 API 请求将 _source 请求正文参数设置为 false。文档来源不包含在响应中。

curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "_source": false,
  "query": {
    "match": {
      "user.id": "kimchy"
    }
  }
}
'

要仅返回源字段的子集,请在 _source 参数中指定通配符 (*) 模式。以下搜索 API 请求仅返回 obj 字段及其属性的源。

curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "_source": "obj.*",
  "query": {
    "match": {
      "user.id": "kimchy"
    }
  }
}
'

您还可以在 _source 字段中指定通配符模式数组。以下搜索 API 请求仅返回 obj1 和 obj2 字段及其属性的源。

curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "_source": [ "obj1.*", "obj2.*" ],
  "query": {
    "match": {
      "user.id": "kimchy"
    }
  }
}
'

为了更好地控制,您可以在 _source 参数中指定一个包含和排除模式数组的对象。

如果指定了包含属性,则仅返回与其模式之一匹配的源字段。您可以使用 excludes 属性从此子集中排除字段。

如果未指定 includes 属性,则返回整个文档源,不包括与 excludes 属性中的模式匹配的任何字段。

以下搜索 API 请求仅返回 obj1 和 obj2 字段及其属性的来源,不包括任何子description字段。

curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "_source": {
    "includes": [ "obj1.*", "obj2.*" ],
    "excludes": [ "*.description" ]
  },
  "query": {
    "term": {
      "user.id": "kimchy"
    }
  }
}
'

跨集群搜索

跨集群搜索可以让一个搜索请求运行在一个或者多个远程的集群上。例如,你使用跨集群搜索去过滤和分析存储在不同数据中心上的日志数据。

提示:跨集群搜索请求必须是远程集群

支持的API

  • Search
  • Async search
  • Multi search
  • Search template
  • Multi search template
  • Field capabilities

跨集群所搜例子

远程集群设置

想要执行一个跨集群搜索,你必须至少要配置一个远程集群。

提示:如果你想要在云上跨集群搜索,你可以在ElasticSearch服务上配置远程集群。然后,您可以跨集群搜索并设置跨集群复制。

根据cluster update settting API请求添加三个远程集群:cluster_one、cluster_two、cluster_three

curl -X PUT "localhost:9200/_cluster/settings?pretty" -H 'Content-Type: application/json' -d'
{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_one": {
          "seeds": [
            "127.0.0.1:9300"
          ]
        },
        "cluster_two": {
          "seeds": [
            "127.0.0.1:9301"
          ]
        },
        "cluster_three": {
          "seeds": [
            "127.0.0.1:9302"
          ]
        }
      }
    }
  }
}
'
在单独远程集群上执行搜索

根据以下search API请求,在cluster_one远程集群上搜索my-index-000001索引:

curl -X GET "localhost:9200/cluster_one:my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "user.id": "kimchy"
    }
  },
  "_source": ["user.id", "message", "http.response.status_code"]
}
'

API响应为:

{
  "took": 150,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0,
    "skipped": 0
  },
  "_clusters": {
    "total": 1,
    "successful": 1,
    "skipped": 0
  },
  "hits": {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "cluster_one:my-index-000001", 
        "_type": "_doc",
        "_id": "0",
        "_score": 1,
        "_source": {
          "user": {
            "id": "kimchy"
          },
          "message": "GET /search HTTP/1.1 200 1070000",
          "http": {
            "response":
              {
                "status_code": 200
              }
          }
        }
      }
    ]
  }
}
在多个远程集群上执行搜索

根据以下查询请求在3个远程集群上执行my-index-000001索引查询

  • 你的本地集群
  • 两个远程集群:cluster_one、cluster_two
curl -X GET "localhost:9200/my-index-000001,cluster_one:my-index-000001,cluster_two:my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "user.id": "kimchy"
    }
  },
  "_source": ["user.id", "message", "http.response.status_code"]
}
'

API响应为:

{
  "took": 150,
  "timed_out": false,
  "num_reduce_phases": 4,
  "_shards": {
    "total": 3,
    "successful": 3,
    "failed": 0,
    "skipped": 0
  },
  "_clusters": {
    "total": 3,
    "successful": 3,
    "skipped": 0
  },
  "hits": {
    "total" : {
        "value": 3,
        "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "my-index-000001", 
        "_type": "_doc",
        "_id": "0",
        "_score": 2,
        "_source": {
          "user": {
            "id": "kimchy"
          },
          "message": "GET /search HTTP/1.1 200 1070000",
          "http": {
            "response":
              {
                "status_code": 200
              }
          }
        }
      },
      {
        "_index": "cluster_one:my-index-000001", 
        "_type": "_doc",
        "_id": "0",
        "_score": 1,
        "_source": {
          "user": {
            "id": "kimchy"
          },
          "message": "GET /search HTTP/1.1 200 1070000",
          "http": {
            "response":
              {
                "status_code": 200
              }
          }
        }
      },
      {
        "_index": "cluster_two:my-index-000001", 
        "_type": "_doc",
        "_id": "0",
        "_score": 1,
        "_source": {
          "user": {
            "id": "kimchy"
          },
          "message": "GET /search HTTP/1.1 200 1070000",
          "http": {
            "response":
              {
                "status_code": 200
              }
          }
        }
      }
    ]
  }
}

跳过无效集群

默认情况下,如果在请求中任何一个集群是无效的,那么跨集群搜索将返回一个错误。

设置集群的skip_unavailabletrue,在跨集群搜索期间跳过一个无效的集群。

根据以下cluster update setting API请求,设置cluster_two集群skip_unavailabletrue

curl -X PUT "localhost:9200/_cluster/settings?pretty" -H 'Content-Type: application/json' -d'
{
  "persistent": {
    "cluster.remote.cluster_two.skip_unavailable": true
  }
}
'

提示:如果在跨集群搜索期间 cluster_two 断开连接或不可用,Elasticsearch 将不会在最终结果中包含来自该集群的匹配文档。

嗅探模式下选择网关和种子节点

对于使用嗅探连接模式的远程集群,需要通过您的网络从本地集群访问网关和种子节点。

默认情况下任何非主节点的节点都可以充当网关节点。你可以通过设置cluster.remote.node.attr.gatewaytrue来定义一个节点为网关节点。

对于跨集群搜索,我们推荐你使用能够充当搜索请求协调节点的节点来担任网关节点。如果需要,集群中的种子节点可以是网关节点的子集。

跨集群搜索怎么处理网络延迟

因为跨集群搜索涉及返送请求到远程集群,任何网络延迟都可能影响搜索速度。为了避免低效率查询,跨集群搜索提供两个选项来处理网络延迟:

  • 最小的网络往返:默认情况下,ElasticSearch会减少远程集群之前的网络往返次数。这样减少了网络延迟对查询速度的影响。然而,ElasticSearch不能减少在很大搜索的请求中减少网络往返次数,其中包含scrollinner hits。可以查看Minimize network roundtrips来学习此选项的工作原理。
  • 不最小网络往返:对于包含scollinner hits的搜索查询,ElasticSearch向每个远程集群发送多个outgoingingoing请求。您还可以通过将 ccs_minimize_roundtrips 参数设置为 false 来选择此选项。虽然通常较慢,但这种方法可能适用于低延迟的网络。可以查看Don’t minimize network roundtrips来学习此选项的工作原理。
Minimize network roundtrips

以下是当您最小化网络往返时跨集群搜索的工作原理。

  • 您向本地集群发送跨集群搜索请求。该集群中的协调节点接收并解析请求。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fu1bzoib-1625541935067)(https://www.elastic.co/guide/en/elasticsearch/reference/current/images/ccs/ccs-min-roundtrip-cluster-search.svg)]

  • 协调节点向每个集群发送单个搜索请求,包括本地集群。每个集群独立执行搜索请求,将其自己的集群级别设置应用于请求。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JDk6QUJV-1625541935070)(https://www.elastic.co/guide/en/elasticsearch/reference/current/images/ccs/ccs-min-roundtrip-cluster-search.svg)]

  • 每个远程集群将其搜索结果发送回协调节点。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uynowr9b-1625541935071)(https://www.elastic.co/guide/en/elasticsearch/reference/current/images/ccs/ccs-min-roundtrip-cluster-results.svg)]

  • 从每个集群收集结果后,协调节点在跨集群搜索响应中返回最终结果。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MAxCj1Iv-1625541935072)(https://www.elastic.co/guide/en/elasticsearch/reference/current/images/ccs/ccs-min-roundtrip-client-response.svg)]

Don’t minimize network roundtripsedit

以下是当您不最小化网络往返时跨集群搜索的工作原理。

  • 您向本地集群发送跨集群搜索请求。该集群中的协调节点接收并解析请求。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qF45hjTJ-1625541935073)(https://www.elastic.co/guide/en/elasticsearch/reference/current/images/ccs/ccs-min-roundtrip-client-request.svg)]

  • 协调节点向每个远程集群发送搜索分片 API 请求。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uy7u2hn9-1625541935074)(https://www.elastic.co/guide/en/elasticsearch/reference/current/images/ccs/ccs-min-roundtrip-cluster-search.svg)]

  • 每个远程集群将其响应发送回协调节点。此响应包含有关将在其上执行跨集群搜索请求的索引和分片的信息。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jpi8tY2d-1625541935074)(https://www.elastic.co/guide/en/elasticsearch/reference/current/images/ccs/ccs-min-roundtrip-cluster-results.svg)]

  • 协调节点向每个分片发送搜索请求,包括其自己集群中的分片。每个分片独立执行搜索请求。

  • 每个分片将其搜索结果发送回协调节点。

  • 从每个集群收集结果后,协调节点在跨集群搜索响应中返回最终结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值