美文网首页
es restapi

es restapi

作者: ljt001 | 来源:发表于2024-12-25 11:20 被阅读0次

https://www.elastic.co/guide/en/elasticsearch/reference/7.17/rest-apis.html
接口契约
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-search.html#search-search-api-example

以下bool查询单一must条件与term、match的效果一样。
但bool查询可以支持更多逻辑组合查询,比如must、should、must_not、filter等。

curl localhost:9200/_cat
curl localhost:9200/_cat/indices
curl localhost:9200/my_index/_search -H 'Content-Type: application/json' -d '{"query": {"term": {"id": 123}}}'
curl localhost:9200/my-index/_search?pretty&from=10&size=20
curl localhost:9200/my-index/_count

# -s参数:静默模式,隐藏curl进度信息;
# column -t:自动对齐列格式
# grep -E 'health|foo':保留标题行和含foo的索引
# v:显示列名标题行(verbose)
# pretty:格式化输出(可选)
curl -s $es/_cat/indices?v | column -t | grep -E 'health|foo'
health  status  index      uuid pri  rep  docs.count  docs.deleted  store.size  pri.store.size
green   open    index_foo  abc  20   1    3406        2169          4.4mb       2.3mb
green   open    index_foo2 xyz  20   1    12583       12269         34.9mb      17.6mb

// 以下只列json条件,都需要header指定为json格式

{"query": {"term": {"name": "foo"}}}
{"query": {"match": {"name": "foo"}}}
// bool查询单一条件
{"query": {"bool": {
    "must": [
        {"match": {"name": "foo"}}
    ]
}}}
// bool查询多条件
{"query": {"bool": {
    "must": [
        {"match": {"id": 1}},
        {"match": {"name": "foo"}}
    ]
}}}
{ "sort": [{"_id": {"order": "desc"}}], "query": {"match_all": {}} }
{"query": {"match": {"name": "foo"}}}
{"query": {"term": {"user.id": "foo" }}}
{"query": { "range": {"age": { "gte": 10, "lte": 20, "boost": 2.0 }}}}

# query.bool.must[term:{},range:{}] 复杂查询,嵌套结构深,不大好理解
{
  "query": {
    "bool": {
      "must": [{
        "term": {"foo_id": 123}
      },
      {
        "range": { "update_time": { "gt": "2025-08-01T00:00:00+08:00", "lte": "2025-08-03T23:59:59+08:00" } }
      }]
    }
  }
}
# 指定时区,据说Elasticsearch 默认使用UTC,不过估计以下time_zone也能识别
"update_time": {
  "gt": "2025-08-01T00:00:00+08:00",
  "lte": "2025-08-03T23:59:59+08:00",
  "time_zone": "+08:00"
}
# 另一种写法,还没试过
{
  "query": {
    "bool": {
      "filter": [  // 使用filter不计算相关性分数,提升性能
        { "term": { "foo_id": 123 }},
        { "range": { "update_time": { ... }}}
      ]
    }
  }
}

# 且条件,terms类似in的意思
{
  "query": {
    "bool": {
      "must": [
        {"term": { "FooName": "foo"}},
        {"terms": {"Name": ["foo","bar"]}}
        ]
    }
  }
}

# 在旧索引上删除别名,同时在新索引上创建别名
curl -XPOST $es/_aliases -H 'Content-Type: application/json' -d '{"actions": [
{ "remove": { "index": "'foo'", "alias": "'f'" } },
{ "remove": { "index": "'bar'", "alias": "'b'" } },
{ "add": { "index": "'foov2'", "alias": "'f'" } },
{ "add": { "index": "'barv2'", "alias": "'b'" } }]}'

# 删除所有文档
curl -XPOST /foo/_delete_by_query?conflicts=proceed -H 'Content-Type: application/json' -d '{"query":{"match_all":{}}}'

# mapping为text时,发现es值既可以是字符串如"foo",也可以是字符串数组如["foo"]
"Name": {
  "type": "text",
  "fields": {
    "keyword": {
      "type": "keyword",
      "ignore_above": 256
    }
  }
}

keyword类型、text类型,term查询、match查询使用的区别

注意:match查询条件中有空格、标点符号等分隔符才会按各分词进行查询,否则不会按分词查询,比如1 2 3因为有空格分析器将 "123" 分词成 "1", "2", "3"进行查找;而123就只会按123进行查询

user_id 为 keyword 类型,且值为123时,term和match两种查法有什么区别?

PUT /users {"mappings": {"properties": {"user_id": {"type": "keyword"}}}
PUT /users {"mappings": {"properties": {"user_id": {"type": "text"}}}

term 查询:精确匹配,适用于不分词的字段(如 keyword 类型)。它不会对查询词进行分析处理,因此适合用于查找特定值的场景,如查找特定ID的用户。
match 查询:模糊匹配或全文搜索,适用于分词的字段(如 text 类型),会对查询词进行分析处理。match 查询会将查询词分词,并尝试匹配文档中所有可能的词项。

Q:user_id 为 keyword 类型,且值为123时,term和match两种查法有什么区别?

user_id 为 keyword 类型时,使用match 查询也会查找 user_id 字段值为 "123" 的文档。尽管 match 查询通常用于全文搜索,并且会对查询词进行分析处理,但由于 user_id 是 keyword 类型,Elasticsearch 仍然不会对 "123" 进行分析处理。因此,match 查询在这种情况下也会直接匹配值为 "123" 的文档。

Q:user_id 为 text类型,且值为1 2 3时,term和match两种查法有什么区别?

如果值为123没有空格就不会分词,两者返回结果是一样的

match 查询也会对 "1 2 3" 进行分析处理,并查找包含这些词项的文档。与 term 查询类似,如果分析器将 "123" 分词成 "1", "2", "3",那么 match 查询会查找包含这些词项的文档。但是,match 查询会根据词项的频率和文档长度等因素计算相关性得分,因此返回的结果可能会根据这些因素进行排序。
区别
匹配结果:两种查询方式都会因为 user_id 是 text 类型而导致意外的匹配结果。它们都会匹配包含 "1", "2", "3" 的文档,而不仅仅是值为 "1 2 3" 的文档。
相关性得分:match 查询会根据相关性得分对结果进行排序,而 term 查询不会。因此,match 查询的结果可能会根据词项的频率和文档长度等因素进行排序,而 term 查询的结果是根据文档的存储顺序返回的。
性能:term 查询通常比 match 查询更高效,因为 term 查询是为精确匹配设计的,而 match 查询的设计初衷是全文搜索,可能会涉及更多的内部处理逻辑。
结论
对于 text 类型的字段,使用 term 查询和 match 查询都会导致意外的匹配结果,因为它们都会对查询词进行分析处理。如果你需要精确匹配 user_id,应该将 user_id 映射为 keyword 类型,而不是 text 类型。这样可以确保 user_id 字段的值不会被分词,从而实现精确匹配。

多字段(multi-field)类型的term、match查询比较

如果user_id 字段被定义为一个多字段(multi-field)类型,其中包含两个子字段:一个是 text 类型,另一个是 keyword 类型。这种映射方式允许你在同一个字段上同时支持全文搜索和精确匹配。

# mapping
"user_id": {
  "type": "text",
  "fields": {
    "keyword": {
      "type": "keyword",
      "ignore_above": 256
    }
  }
}

# term 查询:会精确匹配 user_id.keyword 字段值为 "123" 的文档。查询如下:
curl localhost:9200/users/_search -H 'Content-Type: application/json' -d '{"query": {"term": {"user_id.keyword": "123"}}}'

# match 查询:本例没有空格、标点符号等分隔符,将会按"123"整体来查询。查询如下:
# 如果条件为"1 2 3",因为有空格、标点符号等分隔符,就会查找包含 "1", "2", "3" 的文档,因为 user_id 是 text 类型,Elasticsearch 会对 "123" 进行分析处理。
curl localhost:9200/users/_search -H 'Content-Type: application/json' -d '{"query": {"match": {"user_id": "123"}}}'

本例中的多类型字段,如果条件中没有空格、标点符号等分隔符,term和match查询返回结果是一样的

多字段(Multi-Field)类型

1. 常见的类型和分析器

多字段(multi-field)类型允许你在同一个字段上支持多种查询需求。以下是一些常见的类型和分析器:

  • text 类型:
    • 标准分析器(standard analyzer):默认的分析器,适用于大多数全文搜索场景。
    • lowercase 分析器:将所有字符转换为小写,适用于需要忽略大小写的全文搜索。
    • whitespace 分析器:按空格分词,适用于需要按空格分词的场景。
    • simple 分析器:按非字母字符分词,适用于简单的全文搜索场景。
    • stop 分析器:去除常见的停用词(如“the”, “is”等),适用于需要去除停用词的全文搜索场景。
    • 自定义分析器:你可以定义自己的分析器,包括自定义的分词器、过滤器等,适用于特定的全文搜索需求。
  • keyword 类型:不进行分析处理,适用于需要精确匹配的场景,如用户ID、产品ID等。
  • date 类型:支持多种日期格式,适用于日期时间字段。
  • integerlongfloatdouble 类型:数值类型,支持范围查询、精确匹配等。
  • boolean 类型:布尔值类型,支持精确匹配。

2. mappings示例

PUT /users
{
  "mappings": {
    "properties": {
      "user_id": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          },
          "lowercase": {
            "type": "text",
            "analyzer": "lowercase"
          },
          "whitespace": {
            "type": "text",
            "analyzer": "whitespace"
          },
          "simple": {
            "type": "text",
            "analyzer": "simple"
          },
          "stop": {
            "type": "text",
            "analyzer": "stop"
          }
        }
      },
      "created_at": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||epoch_millis",
        "fields": {
          "keyword": {
            "type": "keyword"
          },
          "lowercase": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
          },
          "whitespace": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
          },
          "simple": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
          },
          "stop": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
          }
        }
      }
    }
  }
}

3. 数据示例

POST /users/_doc
{
  "user_id": "123",
  "created_at": "2023-10-01T12:00:00"
}

POST /users/_doc
{
  "user_id": "134",
  "created_at": "2023-10-02T13:00:00"
}

POST /users/_doc
{
  "user_id": "135",
  "created_at": "2023-10-03T14:00:00"
}

4. 查询示例

# 4.1 精确匹配
# 使用 term 查询查找 created_at.keyword 字段值为 "2023-10-01T12:00:00" 的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"term": {"created_at.keyword": "2023-10-01T12:00:00"}}'

# 4.2 范围查询
# 使用 range 查询查找 created_at 字段在 "2023-10-01" 和 "2023-10-03" 之间的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"range": {"created_at": {"gte": "2023-10-01", "lte": "2023-10-03"}}}'

# 4.3 忽略大小写的日期查询
# 使用 match 查询查找 created_at.lowercase 字段包含 "2023-10-01" 的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"match": {"created_at.lowercase": "2023-10-01"}}'

# 4.4 按空格分词的日期查询
# 使用 match 查询查找 created_at.whitespace 字段包含 "2023-10-01" 的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"match": {"created_at.whitespace": "2023-10-01"}}'

# 4.5 简单分词的日期查询
# 使用 match 查询查找 created_at.simple 字段包含 "2023-10-01" 的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"match": {"created_at.simple": "2023-10-01"}}'

# 4.6 去除停用词的日期查询
# 使用 match 查询查找 created_at.stop 字段包含 "2023-10-01" 的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"match": {"created_at.stop": "2023-10-01"}}'

5. 注意事项

  • 日期格式:确保插入数据时的日期格式与映射中定义的格式一致。
  • 时间戳:如果使用时间戳(如 epoch_millis),确保在查询时使用正确的时间戳格式。

相关文章

网友评论

      本文标题:es restapi

      本文链接:https://www.haomeiwen.com/subject/vootfdtx.html