开发者

ElasticSearch查询文档基本操作实例

开发者 https://www.devze.com 2023-02-03 10:39 出处:网络 作者: 程序员皮卡秋
目录查询文档 & 基本操作按照ID单个按照ID批量查询文档是否存在 & 通过id判断查询部分字段内容查询文档 & 条件查询不附加任何条件相关字段解释基础分页查询url参数body 参数单字段全文索引查询单字段不分
目录
  • 查询文档 & 基本操作
    • 按照ID单个
    • 按照ID批量
    • 查询文档是否存在 & 通过id判断
    • 查询部分字段内容
  • 查询文档 & 条件查询
    • 不附加任何条件
    • 相关字段解释
    • 基础分页查询
    • url参数
    • body 参数
    • 单字段全文索引查询
    • 单字段不分词查询
    • match分词结果
    • match_phrase 不分词查询结果
    • 多字段全文索引查询
    • 范围查询
    • 单字段精确查询
    • 字段精确查询 & 多值
    • 文档包含字段查询
  • 结束语

    查询文档 & 基本操作

    为了方便学习, 本节中所有示例沿用上节的索引

    按照ID单个

    GET class_1/_doc/1
    

    查询结果:

    {
      "_index" : "class_1",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 4,
      "_seq_no" : 4,
      "_primary_term" : 3,
      "found" : true,
      "_source" : {
        "name" : "l",
        "num" : 6
      }
    }
    

    按照ID批量

    GET class_1/_mget
    {
    "ids":[1,2,3]
    }
    

    返回:

    {
      "docs" : [
      编程客栈  {
          "_index" : "class_1",
          "_type" : "_doc",
          "_id" : "1",
          "_version" : 4,
          "_seq_no" : 4,
          "_primary_term" : 3,
          "found" : true,
          "_source" : {
            "name" : "l",
            "num" : 6
          }
        },
        {
          "_index" : "class_1",
          "_type" : "_doc",
          "_id" : "2",
          "found" : false
        },
        {
          "_index" : "class_1",
          "_type" : "_doc",
          "_id" : "3",
          "_version" : 3,
          "_seq_no" : 10,
          "_primary_term" : 4,
          "found" : true,
          "_source" : {
            "num" : 9,
            "name" : "e",
            "age" : 9,
            "desc" : [
              "hhhh"
            ]
          }
        }
      ]
    }
    

    查询文档是否存在 & 通过id判断

    HEAD class_1/_doc/1
    

    返回:

    200 - OK

    HEAD class_1/_doc/1000

    返回:

    404 - Not Found

    查询部分字段内容

    GET class_1/_doc/1?_source_includes=name
    

    返回:

    {
      "_index" : "class_1",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 4,
      "_seq_no" : 4,
      "_primary_term" : 3,
      "found" : true,
      "_source" : {
        "name" : "l"
      }
    }
    

    可以看到只返回了name字段, 以上是一个基本的操作,下面给大家讲下条件查询~

    查询文档 & 条件查询

    查询的复杂度取决于它附加的条件约束,跟我们写sql一样。下面就带大家一步一步看一下ES中如何进行条件查询~

    不附加任何条件

    GET class_1/_search
    

    返回:

    {
      "took" : 15,
      "timed_out" : false,
      "_shards" : {
        "total" : 3,
        "successful" : 3,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 8,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "h2Fg-4UBECmbBdQA6VLg",
            "_score" : 1.0,
            "_source" : {
              "name" : "b",
              "num" : 6
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "iGFt-4UBECmbBdQAnVJe",
            "_score" : 1.0,
            "_source" : {
              "name" : "g",
              "age" : 8
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "iWFt-4UBECmbBdQAnVJg",
            "_score" : 1.0,
            "_source" : {
              "name" : "h",
              "age" : 9
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "imFt-4UBECmbBdQAnVJg",
            "_score" : 1.0,
            "_source" : {
              "name" : "i",
              "age" : 10
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "3",
            "_score" : 1.0,
            "_source" : {
              "num" : 9,
              "name" : "e",
              "age" : 9,
              "desc" : [
                "hhhh"
              ]
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "4",
            "_score" : 1.0,
            "_source" : {
              "name" :php "f",
              "age" : 10,
              "num" : 10
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "RWlfBIUBDuA8yW5cu9wu",
            "_score" : 1.0,
            "_source" : {
              "name" : "一年级",
              "num" : 20
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "1",
            "_score" : 1.0,
            "_source" : {
              "name" : "l",
              "num" : 6
            }
          }
        ]
      }
    }
    

    可以看到索引class_1中的所有数据都是上节添加的。这里提一下,我们也可以添加多个索引一起查,然后返回,用,逗号隔开就可以了

    GET class_1,class_2,class_3/_search
    
    {
      "took" : 7,
      "timed_out" : false,
      "_shards" : {
        "total" : 开发者_开发学习5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 9,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "h2Fg-4UBECmbBdQA6VLg",
            "_score" : 1.0,
            "_source" : {
              "name" : "b",
              "num" : 6
            }
          },
          {
            "_index" : "class编程_2",
            "_type" : "_doc",
            "_id" : "RWlfBIUBDuA8yW5cu9wu",
            "_score" : 1.0,
            "_source" : {
              "name" : "一年级",
              "num" : 20
            }
          },
          ....
        ]
      }
    }
    

    可以看到返回了索引class_2中的数据,并且合并到了一起。

    相关字段解释

    有的小伙伴可能对返回的字段有点陌生,这里给大家统一解释一下:

    {
        "took":"查询操作耗时,单位毫秒",
        "timed_out":"是否超时",
        "_shards":{
            "total":"分片总数",
            "successful":"执行成功分片数",
            "skipped":"执行忽略分片数",
            "failed":"执行失败分片数"
        },
        "hits":{
            "total":{
                "value":"条件查询命中数",
                "relation":"计数规则(eq计数准确/gte计数不准确)"
            },
            "max_score":"最大匹配度分值",
            "hits":[
                {
                    "_index":"命中结果索引",
                    "_id":"命中结果ID",
                    "_score":"命中结果分数",
                    "_source":"命中结果原文档信息"
                }
            ]
        }
    }
    

    下面我们看下带条件的查询~

    基础分页查询

    基本语法: es中通过参数sizefrom来进行基础分页的控制

    • from:指定跳过多少条数据
    • size:指定返回多少条数据

    下面看下示例:

    url参数

    GET class_1/_search?from=2&size=2
    

    返回:

    {
      "took" : 5,
      "timed_out" : false,
      "_shards" : {
        "total" : 3,
        "successful" : 3,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 8,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "iWFt-4UBECmbBdQAnVJg",
            "_score" : 1.0,
            "_source" : {
              "name" : "h",
              "age" : 9
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "imFt-4UBECmbBdQAnVJg",
            "_score" : 1.0,
            "_source" : {
              "name" : "i",
              "age" : 10
            }
          }
        ]
      }
    }
    

    body 参数

    GET class_1/_search
    {
        "from" : 2,
        "size" : 2
    }
    

    返回结果和上面是一样的~

    单字段全文索引查询

    这个大家应该不陌生,前面几节都见过。使用query.match进行查询,match适用与对单个字段基于全文索引进行数据检索。对于全文字段,match使用特定的分词进行全文检索。而对于那些精确值,match同样可以进行精确匹配,match查询短语时,会对短语进行分词,再针对每个词条进行全文检索。

    GET class_1/_search
    {
      "query": {
        "match": {
          "name":"i"
        }
      }
    }
    

    返回:

    {
      "took" : 4,
      "timed_out" : false,
      "_shards" : {
        "total" : 3,
        "successful" : 3,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 1,
          "relation" : "eq"
        },
        "max_score" : 1.3862942,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "imFt-4UBECmbBdQAnVJg",
            "_score" : 1.3862942,
            "_source" : {
              "name" : "i",
              "age" : 10
            }
          }
        ]
      }
    }
    

    单字段不分词查询

    使用query.match_phrase进行查询, 它与match的区别就是不进行分词,干说,可能有点抽象,下面我们通过一个例子给大家分清楚:

    先造点数据进去:

    PUT class_1/_bulk
    { "create":{  } }
    {"name":"I eat apple so haochi1~","num": 1}
    { "create":{  } }
    { "name":"I eat apple so zhen haochi2~","num": 1}
    { "create":{  } }
    {"name":"I eat apple so haochi3~","num": 1}
    

    假设有这么几个句子,现在我有一个需求我要把I eat apple so zhen haochi2~这句话匹配出来

    match分词结果

    GET class_1/_search
    {
      "query": {
        "match": {
          "name": "apple so zhen"
        }
      }
    }
    

    返回:

    {
      "took" : 15,
      "timed_out" : false,
      "_shards" : {
        "total" : 3,
        "successful" : 3,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : 2.2169428,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "cMfcCoYB090miyjed7YE",
            "_score" : 2.2169428,
            "_source" : {
              "name" : "I eat apple so zhen haochi2~",
              "num" : 1
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "b8fcCoYB090miyjed7YE",
            "_score" : 1.505254,
            "_source" : {
              "name" : "I eat apple so haochi1~",
              "num" : 1
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "ccfcCoYB090miyjed7YE",
            "_score" : 1.505254,
            "_source" : {
              "name" : "I eat apple so haochi3~",
              "num" : 1
            }
          }
        ]
      }
    }
    

    从结果来看,刚刚的几句话都被查出来了,但是结果并大符合预期。从score来看,"_score" : 2.2169428得分最高,排在了第一,语句是I eat apple so zhen haochi2~,说明匹配度最高,这个句子正是我们想要的结果~

    match_phrase 不分词查询结果

    GET class_1/_search
    {
      "query": {
        "match_phrase": {
          "name": "apple so zhen"
        }
      }
    }
    

    结果:

    {
      "took" : 6,
      "timed_out" : false,
      "_shards" : {
        "total" : 3,
        "successful" : 3,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 1,
          "relation" : "eq"
        },
        "max_score" : 2.2169428,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "cMfcCoYB090miyjed7YE",
            "_score" : 2.2169428,
            "_source" : {
              "name" : "I eat apple so zhen haochi2~",
              "num" : 1
            }
          }
        ]
      }
    }
    

    结果符合预期,只返回了我们想要的那句。那么match为什么都返回了,这就是前面讲到的分词,首先会对name: apple so zhen进行分词,也就是说存在apple的都会被返回。

    当然,真正业务中的需求比这个复杂多了,这里只是为了给大家做区分~ 下面接着看~

    多字段全文索引查询

    相当于对多个字段执行了match查询, 这里需要注意的是query的类型要和字段类型一致,不然会报类型异常

    GET class_1/_search
    {
      "query": {
        "multi_match": {
          "query": "apple",
          "fields": ["name","desc"]
        }
      }
    }
    
    {
      "took" : 5,
      "timed_out" : false,
      "_shards" : {
        "total" : 3,
        "successful" : 3,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : 0.752627,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "b8fcCoYB090miyjed7YE",
            "_score" : 0.752627,
            "_source" : {
              "name" : "I eat apple so haochi1~",
              "num" : 1
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "ccfcCoYB090miyjed7YE",
            "_score" : 0.752627,
            "_source" : {
              "name" : "I eat apple so haochi3~",
              "num" : 1
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "cMfcCoYB090miyjed7YE",
            "_score" : 0.7389809,
            "_source" : {
              "name" : "I eat apple so zhen haochi2~",
              "num" : 1
            }
          }
        ]
      }
    }
    

    范围查询

    使用range来进行范围查询,适用于数组时间等字段

    GET class_1/_search
    {
      "query": {
        "range": {
          "num": {
            "gt": 5,
            "lt": 10
          }
        }
      }
    }
    

    返回:

    {
      "took" : 6,
      "timed_out" : false,
      "_shards" : {
        "total" : 3,
        "successful" : 3,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "h2Fg-4UBECmbBdQA6VLg",
            "_score" : 1.0,
            "_source" : {
              "name" : "b",
              "num" : 6
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "3",
            "_score" : 1.0,
            "_source" : {
              "num" : 9,
              "name" : "e",
              "age" : 9,
              "desc" : [
                "hhhh"
              ]
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
         编程客栈   "_id" : "1",
            "_score" : 1.0,
            "_source" : {
              "name" : "l",
              "num" : 6
            }
          }
        ]
      }
    }
    

    单字段精确查询

    使用term进行非分词字段的精确查询。需要注意的是,对于那些分词的字段,即使查询的value是一个完全匹配的短语,也无法完成查询

    GET class_1/_search
    {
     "query": {
       "term": {
         "num": {
           "value": "9"
         }
       }
     }
    }
    

    返回:

    {
      "took" : 4,
      "timed_out" : false,
      "_shards" : {
        "total" : 3,
        "successful" : 3,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 1,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "3",
            "_score" : 1.0,
            "_source" : {
              "num" : 9,
              "name" : "e",
              "age" : 9,
              "desc" : [
                "hhhh"
              ]
            }
          }
        ]
      }
    }
    

    字段精确查询 & 多值

    与term一样, 区别在于可以匹配一个字段的多个值,满足一个即检索成功

    GET class_1/_search
    {
     "query": {
       "terms": {
         "num": [
          9,
          1
         ]
       }
     }
    }
    

    返回:

    {
      "took" : 8,
      "timed_out" : false,
      "_shards" : {
        "total" : 3,
        "successful" : 3,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 4,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "3",
            "_score" : 1.0,
            "_source" : {
              "num" : 9,
              "name" : "e",
              "age" : 9,
              "desc" : [
                "hhhh"
              ]
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "b8fcCoYB090miyjed7YE",
            "_score" : 1.0,
            "_source" : {
              "name" : "I eat apple so haochi1~",
              "num" : 1
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "ccfcCoYB090miyjed7YE",
            "_score" : 1.0,
            "_source" : {
              "name" : "I eat apple so haochi3~",
              "num" : 1
            }
          },
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "cMfcCoYB090http://www.devze.commiyjed7YE",
            "_score" : 1.0,
            "_source" : {
              "name" : "I eat apple so zhen haochi2~",
              "num" : 1
            }
          }
        ]
      }
    }
    

    文档包含字段查询

    为了确定当前索引有哪些文档包含了对应的字段,es中使用exists来实现

    GET class_1/_search
    {
      "query": {
        "exists": {
          "field": "desc"
        }
      }
    }
    

    返回:

    {
      "took" : 8,
      "timed_out" : false,
      "_shards" : {
        "total" : 3,
        "successful" : 3,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 1,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "class_1",
            "_type" : "_doc",
            "_id" : "3",
            "_score" : 1.0,
            "_source" : {
              "num" : 9,
              "name" : "e",
              "age" : 9,
              "desc" : [
                "hhhh"
              ]
            }
          }
        ]
      }
    }
    

    结束语

    本节主要讲了ES中的文档查询API操作,该部分内容较多, 下节继续给大家讲,就先消化这么多~API大家都不要去背,多敲几遍就记住了,关键是多用,多总结 。

    以上就是ElasticSearch查询文档基本操作实例的详细内容,更多关于ElasticSearch查询文档的资料请关注我们其它相关文章!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号