zoukankan      html  css  js  c++  java
  • Elasticsearch学习之深入搜索四 --- cross-fields搜索

    1. cross-fields搜索

      一个唯一标识,跨了多个field。比如一个人,标识,是姓名;一个建筑,它的标识是地址。姓名可以散落在多个field中,比如first_name和last_name中,地址可以散落在country,province,city中。跨多个field搜索一个标识,比如搜索一个人名,或者一个地址,就是cross-fields搜索。初步来说,如果要实现,可能用most_fields比较合适。因为best_fields是优先搜索单个field最匹配的结果,cross-fields本身就不是一个field的问题了。

    增添字段:

    POST /forum/article/_bulk
    { "update": { "_id": "1"} }
    { "doc" : {"author_first_name" : "Peter", "author_last_name" : "Smith"} }
    { "update": { "_id": "2"} }
    { "doc" : {"author_first_name" : "Smith", "author_last_name" : "Williams"} }
    { "update": { "_id": "3"} }
    { "doc" : {"author_first_name" : "Jack", "author_last_name" : "Ma"} }
    { "update": { "_id": "4"} }
    { "doc" : {"author_first_name" : "Robbin", "author_last_name" : "Li"} }
    { "update": { "_id": "5"} }
    { "doc" : {"author_first_name" : "Tonny", "author_last_name" : "Peter Smith"} }
    View Code

    查询first_name和last_name中包含Peter Smith的doc

    GET /forum/article/_search
    {
      "query": {
        "multi_match": {
          "query":       "Peter Smith",
          "type":        "most_fields",
          "fields":      [ "author_first_name", "author_last_name" ]
        }
      }
    }

    Peter Smith,匹配author_first_name,匹配到了Smith,这时候它的分数很高,为什么?
      因为IDF分数高,IDF分数要高,那么这个匹配到的term(Smith),在所有doc中的出现频率要低,author_first_name field中,Smith就出现过1次
    Peter Smith这个人,在doc 1,Smith在author_last_name中,但是 author_last_name 出现了两次 Smith,所以导致doc 1的IDF分数较低,这里就存在以下三个问题:

    问题1:只是找到尽可能多的field匹配的doc,而不是某个field完全匹配的doc

      解决,最匹配的document被最先返回

    问题2:most_fields,没办法用minimum_should_match去掉长尾数据,就是匹配的特别少的结果

      解决,可以使用minimum_should_match去掉长尾数据

    问题3:TF/IDF算法,比如Peter Smith和Smith Williams,搜索Peter Smith的时候,由于first_name中很少有Smith的,所以query在所有document中的频率很低,得到的分数很高,可能Smith Williams反而会排在Peter Smith前面

      解决,Smith和Peter在一个field了,所以在所有document中出现的次数是均匀的,不会有极端的偏差,计算IDF的时候,将每个query在每个field中的IDF都取出来,取最小值,就不会出现极端情况下的极大值了

    第一个办法:用copy_to,将多个field组合成一个field

      问题其实就出在有多个field,有多个field以后,就很尴尬,我们只要想办法将一个标识跨在多个field的情况,合并成一个field即可。比如说,一个人名,本来是first_name,last_name,现在合并成一个full_name

    PUT /forum/_mapping/article
    {
      "properties": {
          "new_author_first_name": {
              "type":     "string",
              "copy_to":  "new_author_full_name" 
          },
          "new_author_last_name": {
              "type":     "string",
              "copy_to":  "new_author_full_name" 
          },
          "new_author_full_name": {
              "type":     "string"
          }
      }
    }

    用了这个copy_to语法之后,就可以将多个字段的值拷贝到一个字段中,并建立倒排索引

    POST /forum/article/_bulk
    { "update": { "_id": "1"} }
    { "doc" : {"new_author_first_name" : "Peter", "new_author_last_name" : "Smith"} }        --> Peter Smith
    { "update": { "_id": "2"} }    
    { "doc" : {"new_author_first_name" : "Smith", "new_author_last_name" : "Williams"} }        --> Smith Williams
    { "update": { "_id": "3"} }
    { "doc" : {"new_author_first_name" : "Jack", "new_author_last_name" : "Ma"} }            --> Jack Ma
    { "update": { "_id": "4"} }
    { "doc" : {"new_author_first_name" : "Robbin", "new_author_last_name" : "Li"} }            --> Robbin Li
    { "update": { "_id": "5"} }
    { "doc" : {"new_author_first_name" : "Tonny", "new_author_last_name" : "Peter Smith"} }        --> Tonny Peter Smith
    View Code

    然后查询:

    GET /forum/article/_search
    {
      "query": {
        "match": {
          "new_author_full_name":       "Peter Smith"
        }
      }
    }

     

     

  • 相关阅读:
    Entity Framework 中Decimal字段长度设置方法
    DWZ框架的使用
    .net mvc之web开发体会
    ASP.NET MVC3.0中同一View如何返回多个Model或数据集
    html5中 viewport 的用法
    swagger-REST API
    Git 添加SSH 取消了输入帐号密码
    [转]并发insert情况下会发生重复的数据插入问题
    如何编写适用于Echarts Map的js文件
    [转]OpenLayers 3 自定义坐标系
  • 原文地址:https://www.cnblogs.com/sunfie/p/7102815.html
Copyright © 2011-2022 走看看