【ElasticSearch入门】8、基于词项和全文的分析,结构化搜索

【ElasticSearch入门】8、基于词项和全文的分析,结构化搜索

一、基于term查询

img

  • Term Level Query:Term Query / Range Query / Exists Query / Prefix Query / Wildcard Query
  • 在 ES 中,Term 查询,对输入不做分词。会将输入作为一个整体,在倒排索引中查找准确的词项,并且使用相关度算分公式为每个包含该词项的文档进行相关度算分 - 例如 “Apple Store”
  • 可以通过 Constant Score 将查询转换换成一个 Filtering,避免算分,并利用缓存,提交性能

demo

DELETE products
PUT products
{
  "settings": {
    "number_of_shards": 1
  }
}
 
 //创建索引,插入数据
POST /products/_bulk
{ "index": { "_id": 1 }}
{ "productID" : "XHDK-A-1293-#fJ3","desc":"iPhone" }
{ "index": { "_id": 2 }}
{ "productID" : "KDKE-B-9947-#kL5","desc":"iPad" }
{ "index": { "_id": 3 }}
{ "productID" : "JODL-X-1937-#pV7","desc":"MBP" }

//查询iPhone
POST /products/_search
{
  "query": {
    "term": {
      "desc": {
        "value": "iPhone"
      }
    }
  }
}

image-20220601151233095

没有相关匹配项,原因:因为在插入相关数据时,es分词过程中讲大写字母改为了小写。而term为精准查询,所以没有结果。

将iphone改为小写即产生结果。

image-20220601151414664

或者将其改为keyword查询,也可以将大写iPhone查出来。

POST /products/_search
{
  "query": {
    "term": {
      "desc.keyword": {
        "value": "iPhone"
      }
    }
  }
}

image-20220601151658717

term查询会返回算分结果的。

  • 将 Query 转成 Filter,忽略 TF-IDF 计算,避免相关性算分的开销
  • Filter 可以有效利用缓存
POST /products/_search
{
  "explain": true, 
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "productID.keyword": "XHDK-A-1293-#fJ3"
        }
      }
    }
  }
}

image-20220601151812454

二、基于全文本的查询

img

基于全文本的查找

  • Match Query / Match Phrase Query / Query String Query

特点

  • 索引和搜索时会进行分词,查询字符串先传递到一个合适的分词器,然后生成一个供查询的词项列表
  • 查询时候,先会对输入的查询进行分词。然后每个词项逐个进行底层的查询,最终将结果进行合并。并未每个文档生成一个算分。 例如查 “Martix reloaded”, 会查到包括 Matrix 或者 reload 的所有结果。

img

demo

PUT groups
{
  "mappings": {
    "properties": {
      "names":{
        "type": "text",
        "position_increment_gap": 100 //数组之间每项的gap距离
      }
    }
  }
}
 
GET groups/_mapping
 
POST groups/_doc
{
  "names": [ "John Water", "Water Smith"]
}
 
POST groups/_search
{
  "query": {
    "match_phrase": {
      "names": {
        "query": "Water Water",
        "slop": 0
      }
    }
  }
}

由于每项之间gap的距离为100,而查询时指定slop为0,无法匹配两个water,查询结果为空。

image-20220601152511225

若将slop改为100,则结果如下所示。

image-20220601152623940

全部查出。

img

三、结构化的搜索

结构化数据

结构化搜索(Structured search) 是指对结构化数据的搜索

  • 日期,布尔类型和数字都是结构化

文本也可以是结构化的

  • 如彩色笔可以有离散的颜色集合:红(red)、绿(green)、蓝(blue)
  • 一个博客可能被标记了标签,例如,分布式(distributed)和搜索(search)
  • 电商网站上的商品都有 UPCs(通用产品码 Universal Product Codes)或其他的唯一标识,它们都遵从严格规定的、结构化的格式

img

demo

#结构化搜索,精确匹配
DELETE products
POST /products/_bulk
{ "index": { "_id": 1 }}
{ "price" : 10,"avaliable":true,"date":"2018-01-01", "productID" : "XHDK-A-1293-#fJ3" }
{ "index": { "_id": 2 }}
{ "price" : 20,"avaliable":true,"date":"2019-01-01", "productID" : "KDKE-B-9947-#kL5" }
{ "index": { "_id": 3 }}
{ "price" : 30,"avaliable":true, "productID" : "JODL-X-1937-#pV7" }
{ "index": { "_id": 4 }}
{ "price" : 30,"avaliable":false, "productID" : "QQPX-R-3956-#aD8" }
 
GET products/_mapping

插入部分数据

POST products/_search
{
  "profile": true,
  "explain": true, 
  "query": {
    "term": {
      "avaliable": {
        "value": "true"
      }
    }
  }
}

查询Boolean值

image-20220601154811533

改为constant score+filter型式,减少算分消耗。

POST products/_search
{
  "profile": true,
  "explain": true,
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "avaliable": "true"
        }
      }
    }
  }
}

image-20220601154910112

terms数字查询:

POST products/_search
{
  "profile": true,
  "explain": true,
  "query": {
    "constant_score": {
      "filter": {
        "terms": {
          "price": ["20","30"] //返回price 20 or 30的doc
        }
      }
    }
  }
}

数字范围查询:

POST products/_search
{
  "profile": true,
  "explain": true,
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "price": {
            "gte":20, //返回大于等于 20 小于等于 30的doc
            "lte": 30
          }
        }
      }
    }
  }
}

日期型:

img

POST products/_search
{
  "profile": true,
  "explain": true,
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "date": {
            "gte":"now-4y" //返回大于当前时间四年前的doc
          }
        }
      }
    }
  }
}

exists 查询 - 非空查询

img

处理多值字段

插入数据

#处理多值字段
POST /movies/_bulk
{ "index": { "_id": 1 }}
{ "title" : "Father of the Bridge Part II","year":1995, "genre":"Comedy"}
{ "index": { "_id": 2 }}
{ "title" : "Dave","year":1993,"genre":["Comedy","Romance"] }
 
 
#处理多值字段,term 查询是包含,而不是等于
POST movies/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "genre.keyword": "Comedy" //返回所有genre包含comedy的doc
        }
      }
    }
  }
}

若想返回只有comedy gennre的doc,可以增加一个字段,控制genre数量。

插入doc

POST /movies/_bulk
{ "index": { "_id": 3 }}
{ "title" : "Father of the Bridge Part II","year":1995, "genre":"Comedy","genre_count" : 1}
{ "index": { "_id": 4 }}
{ "title" : "Dave","year":1993,"genre":["Comedy","Romance"],"genre_count" : 2 }

查询

POST movies/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "must":[
                 { "term" : { "genre.keyword" : "Comedy" }}, //只返回comedy类型的doc
                { "term" : { "genre_count" : 1 } }
            ]
        }
      }
    }
  }
}

img

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值