美文网首页
(五)高级搜索1

(五)高级搜索1

作者: 木人呆呆 | 来源:发表于2020-08-10 16:16 被阅读0次

一、基于词项和基于全文的搜索

  1. 基于term的查询
    term 是表达语义的最小单位,搜索和基于统计的语言模型进行自然语言处理都需要处理term
    • 在ES中,Term查询,对输入不做分词,会将输入作为一个整体,在倒排索引中查找准确的词项,并使用相关度算分公式为每个包含包含该词项的文档进行算分
    • 可以通过Constant score将查询转换成一个Filtering,避免算分,并利用缓存,提高性能
//先存入一些数据
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" }

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

//会发现使用“iPhone”检索不出来,只有使用“iphone”才可以检索出来,
//原因就是“desc”字段存入的时候,做了分词,并且转成了小写,用大写的就检索不出来。
//可以使用这种方式先查看分词后的结果,方便检索不到结果时的问题定位
GET _analyze
{
  "analyzer": "standard",
  "text": ["XHDK-A-1293-#fJ3"]
}

以上这些方法可以针对某个字段做匹配查询,ES默认会给Text类型的字段加上keyword属性,在查询的时候可以采用下面例子给出的这种方式,ES会将包含你要检索词条的所有文档都罗列出来(说白了,就是包含而不相等)。

但是如果想精确查询某个字段,这里给出一个精确查询的解决方案?(下文会给出解决方案)

keyword属性

POST /products/_search
{
  "query": {
    "term": {
      "productID.keyword": {             //使用keyword属性就可以精确检索
        "value": "XHDK-A-1293-#fJ3"
      }
    }
  }
}

如果不需要相关性计算,可以使用Constant score将查询转换成filter,从而避免相关性算分机制,还能有效利用缓存功能,能够提升效率

POST /products/_search
{
  "query": {
    "constant_score": {         //使用constant_score,转换成filter
      "filter": {
        "term": {
          "productID.keyword":{
            "value":"XHDK-A-1293-#fJ3"
          }
        }
       }
    } 
  }
}
  1. 基于全文的查询
    基于全文本的检索
    • match query
    • match phrase
    • query string query
      查询的时候,会先对输入的查询进行分词,然后每个词项逐个进行底层的查询,最终将结果进行合并,并且为每个文档生成一个算分,输出计算结果。

展示一个布尔查询的demo

//插入数据
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" }

POST products/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "must_not":{
            "exists":{
              "field":"date"
            }
          }
        }
      }
    }
  }
}

Term查询和全文的查询本质区别在于Term不会做分词,而全文查询会对输入进行分词

三、相关性算分

ES 5 之前默认的相关性算分采用TF-IDF,现在采用BM 25

  1. 词频(Term Frequency) 即检索词在一篇文档中的出现的频率
    • 计算方式为:检索词出现的次数/文档的总字数
    • 度量一条查询和结果文档相关性的简单算法:将搜索中每一个词的TF相加,即 TF(term1)+TF(term2)+TF(term3)
    • Stop word,例如“的”这样的词,对贡献相关度几乎没有帮助,就不应该考虑这些词的TF
  2. 逆文档频率(Inverse Document Frequency,IDF),即检索词在所有文档中出现的频率
    简单的计算公式:log(全部文档数/检索词出现过的文档数),TF-IDF的本质是是将TF求和变成加权求和
    举个例子:区块链的应用
出现的文档数 总文档数 IDF
区块链 200万 10亿 log(500)=8.96
10亿 10亿 log(1)=0
应用 5亿 10亿 log(2)=1

那么“区块链的应用”的TF-IDF相关性计算公式为:
TF(区块链)IDF(区块链)+TF(的)IDF(的)+TF(应用)*IDF(应用)

TF-IDF被公认是信息检索领域最重要的发明,现代的搜索引擎都对TF-IDF进行了细微的优化
ES 可以对索引,字段分别设置boosting参数

//存入数据
PUT testscore/_bulk
{ "index": { "_id": 1 }}
{ "content":"we use Elasticsearch to power the search" }
{ "index": { "_id": 2 }}
{ "content":"we like elasticsearch" }
{ "index": { "_id": 3 }}
{ "content":"The scoring of documents is caculated by the scoring formula" }
{ "index": { "_id": 4 }}
{ "content":"you know, for search" }

//直接查询,会发现"_id"为2的排在前面
POST /testscore/_search
{
   "query": {
    "match": {
      "content": "elasticsearch"
    }
  }
}

//设置boost的值,会对相关性计算的分数产生影响boost>1 增强,0<boost<1 削弱 ,boost<0 会产生负面影响

POST testscore/_search
{
    "query": {
        "boosting" : {
            "positive" : {
                "term" : {
                    "content" : "elasticsearch"
                }
            },
            "negative" : {
                 "term" : {
                     "content" : "like"
                }
            },
            "negative_boost" : 0.2      
        }
    }
}

四、Query Context和Filter Context

在ES中有两种不同的context

  • Query context 相关性算分
  • Filter context 不需要算分,可以利用cache,获得更好的效能提升
    对于多条件组合,可能会组合用到上面两种查询。组合查询中布尔查询又是其中一种常用的查询方式:
must 必须匹配。贡献算分
shoud 选择性匹配。贡献算分
must_not 必须不能匹配。
filter 必须匹配。不贡献算分
这里来回答下上文提出的那个不能精确查询的问题

增加一个count字段进行计数


在创建文档的时候,增加一个count字段,在查询的时候通过组合查询的方式,可以解决精确查询的问题


如果标题和描述中都有相同的内容,想要准确检索,也可以采用类似的办法来处理

//title和content里面都有相同的内容
DELETE blogs
POST /blogs/_bulk
{ "index": { "_id": 1 }}
{"title":"Apple iPad", "content":"Apple iPad,Apple iPad" }
{ "index": { "_id": 2 }}
{"title":"Apple iPad,Apple iPad", "content":"Apple iPad" }

//采用下面这种检索方式,就可以按照自己的想法,是选择从title还是content 中检索了。
POST blogs/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {
          "title": {
            "query": "apple,ipad",
            "boost": 1.1
          }
        }},

        {"match": {
          "content": {
            "query": "apple,ipad",
            "boost":0.5
          }
        }}
      ]
    }
  }
}

相关文章

  • (五)高级搜索1

    一、基于词项和基于全文的搜索 基于term的查询term 是表达语义的最小单位,搜索和基于统计的语言模型进行自然语...

  • 你真的会用搜索引擎吗

    1.关键词搜索,如:查找搜索引擎的高级搜索方法 输入:搜索引擎 高级搜索输出:包含 搜索引擎和高级搜索两个关键词的...

  • 使用Github的高级搜索功能

    使用Github的高级搜索功能 1. 首先,提供Github高级搜索帮助页面 https://help.githu...

  • SEO常用高级搜索指令,你学会了吗?

    1. SEO对于site高级搜索指令的运用 site指令是SEO必用的高级搜索指令之一,SEO主要可用来查找搜索引...

  • google搜索引擎用法

    1.google google搜索法Google hacking例子 Google高级预定义搜索语法如下: int...

  • 高级搜索

    一般就经常使用 "关键词+空格+限定范围"

  • 高级搜索

    剪枝 Alpha-beta 剪枝是一种搜索算法,用以减少极小化极大算法(Minimax 算法)搜索树的节点数。这是...

  • Google 高级搜索

    Google 进阶——高级搜索 Google 作为全球最大的搜索引擎,不仅有简单的普通搜索,还有相对高级的搜索方法...

  • 超级搜索术—快速找到你想找的任何信息!资源!

    搜索方法:1.找什么(明确目标)2.哪里找(垂直搜索渠道,发现更多同类型网站)3.怎么找(掌握高级搜索指令) 搜索...

  • 技能提升:高级搜索指令

    下面就来介绍一下搜索引擎的特殊搜索——高级搜索指令,以下是学习笔记汇总。 1、site: site是最常用的搜索指...

网友评论

      本文标题:(五)高级搜索1

      本文链接:https://www.haomeiwen.com/subject/zvcfdktx.html