Elasticsearch - 检索篇(上)

278 阅读3分钟

1. 索引操作

  • 查询 curl GET ip:port/_cat/indices?v
  • 创建 curl PUT ip:port/test_index?pretty
  • 删除 curlDELETE ip:port/test_index?pretty

2. 基础操作

curl [method] ip:port/index<索引名>/type<类型名>/id<document唯一标识>。

  • 新增

  Elasticsearch会自动建立Index和Type,同时,ES默认会对document的每个field都建立倒排索引,让其可以被搜索。

curl PUT ip:port/{index}/{type}/{id}
{ #document数据 }
  • 查询
curl GET ip:port/{index}/{type}/{id}
  • 替换:使用替换方式去修改商品信息时,document的所有field都需要带上
curl PUT ip:port/{index}/{type}/{id}
{ #document数据 }
  • 更新

curl POST ip:port/{index}/{type}/{id}/_update
{
   "doc":{#document的指定field}
}
  • 删除
curl DELEET ip:port/{index}/{type}/{id}

3. 检索

3.1. 字符串查询

  搜索词一般都是跟在search参数后面,以query string的http请求形式发起检索。

curl GET ip:port/{index}/{type}/_search

# 示例查询
curl GET ip:port/ecommerce/product/_search?q=name:yagao&sort=price:desc
# 返回结果
{
  "took" : 530,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {...}
    ]
  }
}

字段含义说明:

  • took 耗费时长(毫秒)。
  • timed_out 是否超时。
  • _shards 数据拆成的分片数,所以对于搜索请求,会打到所有的primary shard(或者是primary shard对应的某个replica shard)。
  • hits.total 查询结果的数量,3个document。
  • hits.max_score score的含义,就是document对于一个search的相关度的匹配分数,越相关,就越匹配,分数也高。
  • hits.hits 包含了匹配搜索的document的详细数据。

  query string search适用于一些临时、快速的检索请求,如果查询请求很复杂,那么query string search是不太适用的,所以在生产环境中,几乎很少使用query string search。

3.2. DSL

  Domain Specified Language Elasticsearch中很常用的一种检索方式。例如:查询商品名中包含yagao关键子的所有商品,并将结果按照售价排序:

curl GET ip:port/ecommerce/product/_search
{
    "query" : {
        "match" : {
            "name" : "yagao"
        }
    },
    "sort": [
        { "price": "desc" }
    ]
}

  所有查询请求参数全部放到了一个http requstbody里面,所以可以构建复杂的查询,适合生产环境使用。

3.3. 数据过滤

  query filter主要用于对数据进行过滤。例如:我们要搜索商品名称包含“yagao”,且售价大于25元的商品:

curl GET ip:port/ecommerce/product/_search
{
    "query" : {
        "bool" : {
            "must" : {
                "match" : {
                    "name" : "yagao" 
                }
            },
            "filter" : {
                "range" : {
                    "price" : { "gt" : 25 } 
                }
            }
        }
    }
}

  上述bool里面可以封装多个查询条件。

3.4. 全文检索

  full-text search 例如:查询producer字段中包含 producer 或 jiajieshi :

curl GET ip:port/ecommerce/product/_search
{
    "query" : {
        "match" : {
            "producer" : "producer jiajieshi"
        }
    }
}

  match 中空格分隔 producer jiajieshi ,只要producer字段中包含了上述任意一个字符,就都会被检索到。采用全文检索时,返回的每一项数据中有一个 _score 字段,这个就是 相关度分数 的意思,分数越高,则越接近检索词。

3.5. 短语搜索

  phrase search 与全文检索相反。输入的关键字必须在出现指定的文本中,一模一样才匹配。例如:查询producer字段中包含 jiajieshi producer :

curl GET ip:port/ecommerce/product/_search
{
    "query" : {
        "match_phrase" : {
            "producer" : "jiajieshi producer"
        }
    }
}

3.6. 高亮搜索

  highlight search 举个例子,我们希望检索name字段包含 yaogao 的所有商品,然后对检索结果中的 yaogao 文本进行高亮:

curl GET ip:port/ecommerce/product/_search
{
    "query" : {
        "match" : {
            "name" : "yagao"
        }
    },
    "highlight": {
        "fields" : {
            "name" : {}
        }
    }
}

  匹配项的结果里多了个“highlight”字段,里面用高亮了匹配的文本:

{
  "took" : 97,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.13353139,
    "hits" : [
      {
        "_index" : "ecommerce",
        "_type" : "product",
        "_id" : "1",
        "_score" : 0.13353139,
        "_source" : {
          "name" : "gaolujie yagao",
          "desc" : "gaoxiao meibai",
          "price" : 30,
          "producer" : "gaolujie producer",
          "tags" : [
            "meibai",
            "fangzhu"
          ]
        },
       "highlight" : {
          "name" : [
            "gaolujie <em>yagao</em>"
          ]
        }
      }
    ]
  }
}