elasticsearch 其他字段类型详解和范例

本章主要内容

  • elasticsearch 中别名字段的详解和范例
  • elasticsearch 中二进制类型的详解和范例
  • elasticsearch 中的嵌套类型的详解和范例
  • elasticsearch 中的范围类型的详解和范例
  • elasticsearch 中的排名类型的详解和范例
  • elasticsearch 中的ip类型的详解和范例
  • elasticsearch 中的search-as-you-type 类型 的详解和范例
  • elasticsearch 中的token_count 类型 的详解和范例

概要

本篇文章主要讲解elasticsearch在业务中经常用到的字段类型,通过大量的范例来学习和理解不同字段类型的应用场景。范例elasticsearch使用的版本为7.17.5。

简述

在Elasticsearch的映射关系中,每个字段都对应一个数据类型或者字段类型,这些类型规范了字段存储的值和用途。

内容

elasticsearch 中别名字段的详解

  • alias(别名)类型可以为索引中的字段定义一个替代名称。

elasticsearch 中别名字段的范例

#创建名为userinfo的索引库并为其创建映射关系
PUT userinfo
{
  "mappings": {
    "properties": {
      "age": {
        "type": "long"
      },
      "aliasage": {
        "type": "alias",
        "path": "age"
      },
      "transit_mode": {
        "type": "keyword"
      }
    }
  }
}
  • 这是一个创建名为"userinfo"的索引的请求。该索引定义了三个字段:
    • "age"字段,它是一个长整型字段。它存储用户的年龄信息。
    • "aliasage"字段,它是一个别名类型的字段。它通过指定"age"字段的路径作为别名的路径,将"aliasage"字段与"age"字段关联在一起。这样,对"aliasage"字段的搜索、聚合和排序操作将与对"age"字段进行的操作一样。
    • "transit_mode"字段,它是一个关键字类型的字段。它存储用户的交通方式信息。
#以上语句创建了userinfo索引库,而且为age字段创建了名为aliasage的别名。
#在索引库userinfo中插入一条文档数据
PUT userinfo/_doc/1
{
  "age": 39,
  "transit_mode": "transit_mode"
}

#通过年龄查询大于30的用户信息
GET userinfo/_doc/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 30
      }
    }
  }
}

#通过别名查询年龄大于30的用户信息
GET userinfo/_doc/_search
{
  "query": {
    "range": {
      "aliasage": {
        "gte": 30
      }
    }
  }
}

#通过年龄、别名查询返回的结果信息如下
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "userinfo",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "age" : 39,
          "transit_mode" : "transit_mode"
        }
      }
    ]
  }
}
  • 需要注意的是,别名字段只能作为查询的目标,而不能作为源字段。也就是说,你不能将文档数据写入"aliasage"字段,只能写入"age"字段。另外,别名的路径也必须指向实际存在的字段。如果路径指向的字段不存在,则会发生错误。

elasticsearch 其他字段类型详解和范例_第1张图片

elasticsearch 中二进制类型的详解

  • 在 Elasticsearch 中,二进制字段的数据必须是 Base64 编码的字符串。这是因为 Elasticsearch 使用 JSON 作为其数据交换格式,而 JSON 不支持原始二进制数据。通过将二进制数据转换为 Base64 编码的字符串,可以确保数据在传输过程中不会出现问题。
  • 在 Elasticsearch 中,二进制类型(binary)用于存储和检索原始的二进制数据。通常情况下,Elasticsearch 主要用于处理结构化或半结构化的文本数据,但在某些场景下,您可能需要处理二进制数据,例如图片、音频、视频或其他非文本数据。在这种情况下,您可以使用二进制类型将这些数据存储在 Elasticsearch 中。

elasticsearch 中二进制类型的范例

#创建索引映射并指定blob字段的类型为二进制类型
PUT myindex-2_02
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "blob": {
        "type": "binary"
      }
    }
  }
}

#在索引库中插入数据,blob的内容是Base64编码的字符串
PUT myindex-2_02/_doc/1
{
  "name":"Some binary blob",
  "blob":"c2FkZw=="
}
  • 需要注意的是,二进制类型字段不支持全文搜索功能,因为这些字段存储的数据通常不是文本数据。此外,在处理大量的二进制数据时,Elasticsearch 的性能可能会受到影响。因此,在使用二进制类型时,请确保您了解其限制,并确保 Elasticsearch 适用于您的用例。
  • 最后,请记住,Elasticsearch 不是专门针对存储和检索大量二进制数据而设计的。根据您的需求,您可能需要评估其他数据存储解决方案(如分布式文件系统或对象存储),这些解决方案可能更适合处理大量二进制数据。在这种情况下,您可以将 Elasticsearch 用于存储和搜索元数据,而将实际的二进制数据存储在其他系统中。

elasticsearch 中的嵌套类型的详解

  • 嵌套类型用于在 Elasticsearch 文档中表示对象数组,它允许您对数组中的对象进行独立查询和过滤。这是处理具有父子关系或层次结构的数据非常有用的方法。

elasticsearch 中的嵌套类型的范例

  • 定义嵌套类型:在 Elasticsearch 的映射中,通过将字段类型设置为 "nested",可以定义嵌套类型
#创建索引映射并指定user字段为一个嵌套类型
PUT myindex-2_07
{
  "mappings": {
    "properties": {
      "user":{
        "type": "nested"
      }
    }
  }
}
  • 索引嵌套文档:使用嵌套类型时,可以将多个对象作为数组索引到 Elasticsearch 中。
#在索引库中插入文档数据,user字段中嵌套了键值对
PUT myindex-2_07/_doc/1
{
  "group": "fans",
  "user": [
    {
      "first": "John",
      "last": "Smith"
    },
    {
      "first": "Alice",
      "last": "White"
    }
  ]
}
  • 查询嵌套文档:要查询嵌套文档,需要使用 "nested" 查询。
#查询user索引库字段中user.first的值是Alice以及User.last的值是Smith的结果
GET myindex-2_07/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "user.first": "Alice"
              }
            },
            {
              "match": {
                "user.last": "Smith"
              }
            }
          ]
        }
      }
    }
  }
}
  • 以上查询语句中需要注意的是,利用嵌套字段进行筛选查询时,必须两个字段值都要符合条件,如果其中一个字段值不满足查询条件,则从索引库中查询不到任何数据,执行结果如图所示:

    elasticsearch 其他字段类型详解和范例_第2张图片

  • 嵌套类型在处理具有复杂关系的文档时非常有用。使用嵌套类型,可以在 Elasticsearch 中更有效地查询和过滤对象数组,并获取所需的详细信息。

elasticsearch 中的范围类型的详解

  • 范围类型 (range type) 是 Elasticsearch 中一种特殊的字段类型,它可以表示一个连续的范围或间隔.
  • range(范围)类型表示介于上限和下限之间的连续值范围,可以使用运算符gt(大于)、gte(大于等于)、lt(小于)、lte(小于等于)定义存储文档的数据范围。每一种范围类型的说明表如下:

范围类型

说明

integer_range

表示由符号的32位整数

float_range

表示单精度浮点数

long_range

表示有符号的64位整数

double_range

表示双精度浮点数

date_range

表示日期范围,可以通过format映射参数支持各种日期格式。无论使用哪种格式,日期值都会被解析为一个无符号的64位整数,该整数为纪元以来的毫秒数。

ip_range

表示IPv4或IPv6地址的一系列IP值

  • 范围类型的主要应用场景是对某个范围内的值进行查询和过滤。例如,查找生产日期在特定日期范围内的商品,或者查找价格在特定范围内的房屋等。

elasticsearch 中的范围类型的范例

#创建索引映射,并指定expected_attendees字段类型为整数范围类型,time_frame字段类型为日期范围类型
PUT myindex-2_08
{
  "mappings": {
    "properties": {
      "expected_attendees": {
        "type": "integer_range"
      },
      "time_frame":{
        "type": "date_range",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      }
    }
  }
}

#插入文档数据
PUT myindex-2_08/_doc/1?refresh
{
  "expected_attendees":{
    "gte":10,
    "lt":20
  },
  "time_frame":{
    "gte":"2021-10-31 12:00:00",
    "lte":"2021-11-01"
  }
}
  • 查询满足expected_attendees字段中数据范围内包含12的文档数据
GET myindex-2_08/_search
{
  "query": {
    "term": {
      "expected_attendees": {
        "value": "12"
      }
    }
  }
}

elasticsearch 其他字段类型详解和范例_第3张图片

  • 根据日期范围查询符合条件的文档数据
#根据日期范围查询符合条件的文档数据
GET myindex-2_08/_search
{
  "query": {
    "range": {
      "time_frame": {
        "gte": "2021-10-31",
        "lte": "2021-11-01",
        "relation": "within"
      }
    }
  }
}

elasticsearch 其他字段类型详解和范例_第4张图片

  • 由以上结果可知,只要范围类型字段的内容包含在筛选的范围内,就会返回当前文档的内容。
  • 总之,Elasticsearch 中的范围类型提供了对连续范围或间隔的查询和过滤功能,支持整数、长整数、浮点数、双精度浮点数、日期和 IP 地址等多种数据类型。这使得在特定范围内对数据进行筛选和分析变得更加简单和高效。

elasticsearch 中的排名类型的详解

  • rank_feature(排名)类型的字段可以存储数字,并且对搜索文档的分数有所影响(搜索文档的分数就是用户搜索的内容和搜索返回文档的匹配度,分数越高,就表示匹配度越高)
  • 这种字段类型在特定场景下非常有用,例如,当您需要根据某些特征对文档进行排序时。例如,电商网站中的产品排名,根据销量、评价等特征对产品进行排序。
  • rank_feature 字段的主要优势在于它可以在查询时高效地为文档评分。Elasticsearch 会在索引时预先计算相关的评分数据,从而加快查询性能。

elasticsearch 中的排名类型的范例

#创建索引映射并将"pagerank"和"topics"这两个字段类型分别指定为"rank_feature"类型和"rank_features"类型
PUT myindex-2_10
{
  "mappings": {
    "properties": {
      "pagerank":{
        "type": "rank_feature"
      },
      "url_length":{
        "type": "rank_feature",
        "positive_score_impact":false
      },
      "topics":{
        "type": "rank_features"
      }
    }
  }
}

#在索引库中插入数据
PUT myindex-2_10/_doc/1
{
  "url": "http://en.wikipedia.org/wiki/2016_Summer_Olympics",
  "content": "Rio 2016",
  "pagerank": 50.3,
  "url_length": 42,
  "topics": {
    "sports": 50,
    "brazil": 30
  }
}

#在索引库中插入数据
PUT myindex-2_10/_doc/2
{
  "url": "http://en.wikipedia.org/wiki/2016_Brazilian_Grand_Prix",
  "content": "Formula One motor race held on 13 November 2016 at the Autodromo Jose Carlos Pace in Sao Paulo,Brazil",
  "pagerank": 50.3,
  "url_length": 47,
  "topics": {
    "sports": 50,
    "brazil": 20,
    "formula one":65
  }
}

#在索引库中插入数据
PUT myindex-2_10/_doc/3
{
  "url": "http://en.wikipedia.org/wiki/Deadpool_(film)",
  "content": "Deadpool is a 2016 American superhero film",
  "pagerank": 50.3,
  "url_length": 37,
  "topics": {
    "movies":60,
    "super hero":65
  }
}

#查询索引库的content字段值中包含"2016"的文档,并根据评分(score字段的值)排序输出
GET myindex-2_10/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content": "2016"
          }
        }
      ],
      "should": [
        {
          "rank_feature": {
            "field": "pagerank"
          }
        },
        {
          "rank_feature": {
            "field": "url_length",
            "boost": 0.1
          }
        },
        {
          "rank_feature": {
            "field": "topics.sports",
            "boost": 0.4
          }
        }
      ]
    }
  }
}
  • 返回的查询结果如图:

    elasticsearch 其他字段类型详解和范例_第5张图片

  • 由以上语句可知,rank_feature字段类型和rank_feaures字段类型只能搭配rank_feature参数进行查询。

elasticsearch 中的ip类型的详解

  • IP 类型用于存储和搜索 IPv4 和 IPv6 地址。它允许您高效地索引和查询 IP 地址数据,因此在处理网络日志、安全分析等场景时非常有用。
  • IP 类型的字段定义如下:
{
  "mappings": {
    "properties": {
      "ip_field": {
        "type": "ip"
      }
    }
  }
}

elasticsearch 中的ip类型的范例

  • 存储和查询 IPv4 和 IPv6 地址。Elasticsearch 可以处理 IPv4 和 IPv6 地址。
PUT my-index/_doc/1
{
  "ip_field": "192.168.1.1"
}

PUT my-index/_doc/2
{
  "ip_field": "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
}
  • 范围查询。您可以使用范围查询来查找特定 IP 地址范围内的文档。
GET my-index/_search
{
  "query": {
    "range": {
      "ip_field": {
        "gte": "192.168.1.1",
        "lte": "192.168.1.10"
      }
    }
  }
}
  • CIDR 符号。您还可以使用 CIDR 符号来查询特定子网内的 IP 地址。
GET my-index/_search
{
  "query": {
    "term": {
      "ip_field": "192.168.1.0/24"
    }
  }
}
  • 排序和聚合。Elasticsearch 允许您根据 IP 地址对结果进行排序和聚合。
GET my-index/_search
{
  "sort": [
    {
      "ip_field": {
        "order": "asc"
      }
    }
  ]
}
  • 注意事项:
    • IP 类型只能用于存储 IP 地址。不要将其用于其他类型的数据。
    • 如果您的数据包含可能包含非 IP 地址的字符串,请在索引之前进行清理或使用关键字类型进行索引。
  • 总之,Elasticsearch 中的 IP 类型为处理 IP 地址数据提供了丰富的功能,使得在网络分析、安全监控等场景中非常实用。

elasticsearch 中的search-as-you-type 类型 的详解

  • search_as_you_type字段类型和text字段类型很相似,Elasticsearch对其进行了优化,为用户提供了开箱即用的功能。search_as_you_type字段类型的字段可以创建一系列的子字段
  • Search-as-you-type 是 Elasticsearch 中的一种特殊字段类型,用于实现实时的、基于部分输入的搜索建议功能。这种类型通过对输入的数据进行分析和索引,使得用户在输入查询的过程中就能看到相关的搜索建议。
  • search-as-you-type 字段类型的主要特点如下:
    • 分词器(Tokenizer)和分析器(Analyzer):为了实现部分匹配,search-as-you-type 字段类型使用了一种特殊的分词器和分析器。它们能够将输入的文本划分为多个递增的令牌(token),从而实现部分匹配。这些令牌会被存储在倒排索引中,以便在搜索时匹配。
    • 边缘 N-gram:为了提高搜索建议的相关性,search-as-you-type 字段类型使用了边缘 N-gram 技术。这种技术可以将输入的文本切分成一个个递增的子字符串,从而在搜索时能够实现部分匹配。这对于处理拼写错误、缩写或其他输入不完整的情况非常有用。
    • 实时性:search-as-you-type 字段类型提供了实时的搜索建议功能,这意味着当用户输入查询时,系统会立即返回与部分输入匹配的建议。这种实时性可以帮助用户更快地找到他们想要的信息,提高搜索体验。

elasticsearch 中的search-as-you-type 类型 的范例

  • 为了使用 search-as-you-type 字段类型,你需要在映射(mapping)中定义该字段。例如:
{
  "mappings": {
    "properties": {
      "title": {
        "type": "search_as_you_type"
      }
    }
  }
}
  • 当执行下面的映射模板时,将会为my_field字段创建下表中的所有字段作为其子字段。

创建的字段

说明

my_field

按照映射中的配置进行分析,如果未配置分词器,则使用索引的默认分词器

my_field._2gram

用大小为2的shingle token filter 分词器对 ny_field进行分词

my_field._3gram

用大小为3的shingle token filter 分词器对 ny_field进行分词

my_field._index_prefix

用edge ngram token filter 打包 my_field._3gram的分词器

  • 在这个例子中,我们为文档的 "title" 字段定义了 search-as-you-type 类型。之后,在索引文档时,Elasticsearch 会自动使用相应的分析器和分词器处理该字段。
  • 当你要查询 search-as-you-type 字段时,可以使用 "multi_match" 查询类型,并指定 "type" 为 "bool_prefix"。例如:
{
  "query": {
    "multi_match": {
      "query": "search text",
      "type": "bool_prefix",
      "fields": [
        "title",
        "title._2gram",
        "title._3gram"
      ]
    }
  }
}
  • 这个查询会在 "title" 字段及其 N-gram 子字段上执行部分匹配查询,返回与输入文本匹配的文档。这样,用户就可以在输入过程中获得相关的搜索建议。
  • 总之,search-as-you-type 字段类型是 Elasticsearch 中一种实现实时搜索建议功能的有效方式。通过使用特殊的分词器

elasticsearch 中的token_count 类型 的详解

  • token_count(令牌计数)类型的字段实际上是一个integer类型字段,它可以对内容进行分词分析,存储内容被分词的数量
  • 用途:token_count 类型用于计算给定文本中的词元数量。它通常与 text 类型字段一起使用,因为这些字段包含实际的文本数据。
  • 分析器:您可以为 token_count 类型指定一个分析器。分析器负责将文本拆分为词元。在默认情况下,Elasticsearch 使用标准分析器。如果需要,可以自定义分析器来满足特定的需求。
  • 需要注意的是,token_count 类型不适用于全文搜索,而主要用于过滤、排序和聚合操作。此外,词元数量不会随着文本的变化而更新,因此,如果文本内容发生更改,需要重新索引文档以更新词元计数。

elasticsearch 中的token_count 类型 的范例

#创建索引映射,给name字段添加子对象,其名称是length,类型是token_count,使用standard分词器进行分词
PUT myindex-tokencount
{
  "mappings": {
    "properties": {
      "name":{
        "type": "text", 
        "fields": {
          "length":{
            "type":"token_count",
            "analyzer":"standard"
          }
        }
      }
    }
  }
}

#添加文档数据
PUT myindex-tokencount/_doc/1
{
  "name":"John Smith"
}

#添加文档数据
PUT myindex-tokencount/_doc/2?pretty
{
  "name":"Rachel Alice Williams"
}

PUT myindex-tokencount/_doc/3
{
  "name":"长大"
}

#查询索引库中name字段被分词后,分词的数量等于2的文档
GET myindex-tokencount/_search
{
  "query": {
    "term": {
      "name.length": {
        "value": "2"
      }
    }
  }
}

elasticsearch 其他字段类型详解和范例_第6张图片

  • 可以看到"John Smith"被standard分词为"John"和"Smith",所以分词数量是2。上面的返回结果符合预期。在查询过程中,我们还可以使用分析语句对查询的内容进行预判分析,范例如下:
#使用standard分词器对内容"John Smith"进行分词处理,返回分词后的结果
GET myindex-tokencount/_analyze
{
  "analyzer": "standard",
  "text":["John Smith"]
}

elasticsearch 其他字段类型详解和范例_第7张图片

  • 以上结果与我们预想的一样,"Joh Smith"被分词成两个单词,还记录了具体分词的单词在原始内容的偏移量。

你可能感兴趣的:(elasticsearch,elasticsearch,搜索引擎,大数据,全文检索,java)