ES基础使用与理解

各语言对接ES,可由客户端client调用内置的API方法,然后转换为JSON格式的DSL语句进行交互,通过http请求调用ES提供的restful风格的API接口。

客户端库的工作流程:

API 调用:开发者使用客户端库提供的高级 API 方法,比如 client.index() 或者 client.search()。
转换为 RESTful 请求:客户端库内部会将这些方法调用转换为对应的 HTTP 请求(如 PUT、GET、POST、DELETE等),并准备好相应的 JSON 数据体。
发送 HTTP 请求:客户端库通过网络发送这些 HTTP 请求到 Elasticsearch 服务器。
处理响应:Elasticsearch 服务器接收到请求后,处理请求并返回响应结果,通常是 JSON 格式的响应。
解析响应:客户端库将 JSON 格式的响应解析为该语言中的对象或数据结构,以便开发者进一步处理。

关于 DSL(Domain Specific Language):

Elasticsearch 使用一种基于 JSON 的领域特定语言 (DSL) 来表达复杂的查询和其他操作。这种 DSL 允许用户定义复杂的搜索条件,例如布尔逻辑、范围查询、匹配短语等。客户端库通常会自动将这些复杂的查询构造为 DSL 并发送给 Elasticsearch。

ES DSL基础使用

查询所有文档

GET /indexname/_search

查询所有文档(elasticsearch 默认情况下只返回top10的文档数据)

GET /indexname/_search
{
  "query": {
    "match_all": {
    }
  }
}

使用ik分词器插件-最细分词(ik_max_word)和智能分词(ik_smart),创建type _doc类型时mappings时定义字段text类型,且不定义分词模式则使用默认(内置的standard)

POST /_analyze
{
  "tokenizer": "ik_max_word", 
  "text":"阻焊显影机XXXXXXXX"
}

重新加载配置:这个 API 主要用于重新加载 IK 分词器的配置文件,例如自定义词典(用户词典)。当您对配置文件进行了修改并希望让这些更改立即生效时,可以使用此 API(无需重启ES服务)

POST /_plugins/_ik/reload

精确查询(ids)根据ES自动生成的唯一_id精确查询(该_id也可以插入文档时指定需关联入库的自定义id)

GET /indexname/_search
{
  "query": {
    "ids":{
      "values": ["1","123","666123"]
    }
  }
}

全文检索单个字段

GET /indexname/_search
{
  "query":{
    "match":{
      "content": "测试一下XXXX"
    }
  }
}

全文检索多个字段(一般如需全文检索多个字段,可采取组合字段的模式-然后使用match(同单个字段-全文检索),查询性能会比较好)

GET /indexname/_search
{
  "query":{
    "multi_match": {
      "query": "测试一下XXXX",
      "fields":["name","sketch"]
    }
  }
}

精确查询(term查询)

GET /indexname/_search
{
  "query": {
    "term":{
      "title":{
        "value":"title名称"
      }
    }
  }
}

等价于(指定value键可舍去,直接"字段":"具体查询value值")

GET /indexname/_search
{
  "query": {
    "term":{
      "title":"title名称"
    }
  }
}

range查询(范围查询,一般应用在对数值类型做范围过滤的时候。比如做价格范围过滤。)

GET /indexname/_search
{
  "query": {
    "range": {
      "FIELD": {
        "gte": 10,
        "lte": 20
      }
    }
  }
}

在 Elasticsearch 中,一旦索引已经被创建并包含了数据,你不能直接修改已存在的映射(mappings)中的字段索引状态。也就是说,你不能直接更改 title 字段的 index 属性从 false 变为 true(需1.创建新的索引库 2.重新索引数据,把旧索引数据复制到新索引 3.最后删除旧索引)

PUT /indexname
{
  "mappings": {
    "properties": {
      "name": {
        "type": "keyword"
      },
      "content": {
        "type": "text",
        "analyzer": "ik_smart"
      },
      "time": {
        "type": "date"
      }
    }
  }
}

从source复制索引库生成新的new_indexname索引库

POST /_reindex
{
  "source": {
    "index": "indexname"
  },
  "dest": {
    "index": "new_indexname"
  }
}

删除索引库

DELETE /indexname

假设你想检查集群的健康状态

GET /_cluster/health

复合查询(fuction score:算分函数查询,可以控制文档相关性算分,控制文档排名)

"operator": "and"-所有分词词条都匹配,才返回对应的文档
query(原始查询,可以是任意条件)
functions(算分函数)
filter(满足的条件,品牌必须是如家【品牌是如家的才加分,这里是加分条件】,此场景表现为加分函数)

GET /indexname/_search
{
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "content": {
                  "query": "XXX电动机",
                  "operator": "and"
                }
              }
            }
          ]
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "time": "yyyy-MM-dd"
            }
          },
          "weight": 2
        }
      ],
      "boost_mode": "sum"
    }
  }
}

复合查询(任意一个词条匹配则返回文档-不写则默认为"operator": "or")

GET /indexname/_search
{
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "content": {
                  "query": "XXXXXX在多少日有出现过?",
                  "operator": "or"
                }
              }
            }
          ]
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "time": "yyyy-MM-dd"
            }
          },
          "weight": 2
        }
      ],
      "boost_mode": "sum"
    }
  }
}

等价于

GET /indexname/_search
{
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "content":"XXXX在多少日出现过?"
              }
            }
          ]
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "time": "yyyy-MM-dd"
            }
          },
          "weight": 2
        }
      ],
      "boost_mode": "sum"
    }
  }
}

在自定义扩展词典新增词条后,只对后续入库的文档数据生效,历史数据的倒排索引列表还是使用之前的分词列表数据,所以新增的分词未生效,在不重新导入历史文档的场景下,通过_update_by_query去更新匹配的文档,如果没有指定查询,那么就会在每个文档上执行更新(conflicts=proceed即表示如果更新过程中发生异常冲突-继续执行)

POST /indexname/_update_by_query?conflicts=proceed

复合查询(bool/must/filter混用),且设置高度(界面还需要增加对EM标签增加CSS样式等)

GET /indexname/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content": "全文检索内容content"
          }
        }
      ],
      "should": [
        {
          "term":{
            "name":"name名称"
          }
        },
        {
          "match": {
            "content": "测试一下"
          }
        },
        {
          "term":{
            "time":"yyyy-MM-dd"
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "name": "XXX名称"
          }
        }
      ],
      "filter": [
        {
          "term": {
            "name": "XXX名称"
          }
        }
      ]
    }
  },
  "highlight": {
    "fields": { 
      "content": { 
        "pre_tags": "<em>",  
        "post_tags": "</em>" 
      }
    }
  }
}

设置搜索结果(分页/排序等)

在使用排序后就不会进行算分了,根据排序设置的规则排列
普通字段是根据字典序排序
地理坐标是根据举例远近排序
排序条件是一个数组,也就是可以写多个排序条件。按照声明的顺序,当第一个条件相等时,再按照第二个条件排序,以此类推
elasticsearch会禁止from+ size 超过10000的请求

GET /indexname/_search
{
  "query": {
    "match": {
      "content": "测试一下"
    }
  },
  "from": 0,
  "size": 10,
  "sort": [
    {
      "time": {
        "order": "asc"
      }
    }
  ]
}
posted @ 2024-07-28 16:53  QAQhong  阅读(3)  评论(0编辑  收藏  举报