ElasticSearch查询文档基本操作实例

2023-02-03 09:44:07
目录
查询文档 & 基本操作按照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"
        ]
      }
    }
  ]
}

查询文档是否存在>
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" : "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" : "cMfcCoYB090miyjed7YE",
            "_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查询文档的资料请关注易采站长站其它相关文章!