0
点赞
收藏
分享

微信扫一扫

ElasticSearch基本技术点

千行 2022-03-21 阅读 39

倒排索引

倒排索引包含两个部分:单词词典、倒排列表。

单词词典(Term Dictionary)

记录所有文档的单词,记录单词到倒排列表的关联关系

单词词典一般比较大,可以通过B+树或哈希拉链法实现,以满足高性能的插入与查询

倒排列表(Posting List)

 记录了单词对应的文档结合,有倒排索引项组成

倒排索引项(Posting)

  • 文档ID
  • 词频(TF)- 该单词在文档中出现的次数,用于相关性评分
  • 位置(Position)- 单词在文档中分词的位置,用于语句搜索
  • 偏移(Offset)- 记录单词的开始和结束位置,实现高亮显示        

 Analysis

文本分析是把全文本转换成一系列单词(term/token)的过程,也叫分词。Analysis是通过Analyzer来实现的,可使用ES内置的分词器或者按需定制化的分析器。除了在数据写入时转换词条,匹配Query语句时候也需要用相同的分析器对查询语句进行分析。

Analyzer的组成

分词器是专门处理分词的组件,Analyzer由三部分组成:

  • Character Filter :针对原始文本处理,例如去除html
  • Tokenizer :按照规则切分单词
  • Token Filter:将切分的单词进行加工,如小写、删除stopwords、增加同义词等

自定义分词器

PUT /my_index
{
    "settings":{
        "analysis":{
            "char_filter":{
                "&_to_and":{
                    "type":"mapping",
                    "mappings":[
                        "&=> and "
                    ]
                }
            },
            "filter":{
                "my_stopwords":{
                    "type":"stop",
                    "stopwords":[
                        "the",
                        "a"
                    ]
                }
            },
            "tokenizer": {
                "my_tokenizer": {
                    "type": "standard"
                }
            },
            "analyzer":{
                "my_analyzer":{
                    "type":"custom",
                    "char_filter":[
                        "html_strip", 
                        "&_to_and"  
                    ],
                    "tokenizer":"my_tokenizer",
                    "filter":[
                        "lowercase", 
                        "my_stopwords"
                    ]
                }
            }
        }
    }
}

多字段类型

多字段特性: 

  • 厂商名字实现精确匹配(增加一个keyword字段)
  • 使用不同的analyzer(不同语言、pinyin字段搜索、还支持为搜索和索引指定不同的analyzer)
PUT products
{
  "mappings": {
    "properties": {
      "company": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "comment": {
        "type": "text",
        "fields": {
          "english_comment": {
            "type": "text",
            "analyzer": "english",
            "search_analyzer": "english"
          }
        }
      }
    }
  }
}

tmdb实例测试

创建mapping

#tmdb创建
PUT movie
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "english"
      },
      "tagline": {
        "type": "text",
        "analyzer": "english"
      },
      "release_date": {
        "type": "date",
        "format": "8yyyy/MM/dd||yyyy/M/dd||yyyy/MM/d||yyyy/M/d"
      },
      "popularity": {
        "type": "double"
      },
      "overview": {
        "type": "text",
        "analyzer": "english"
      },
      "cast": {
        "type": "object",
        "properties": {
          "character": {
            "type": "text",
            "analyzer": "standard"
          },
          "name": {
            "type": "text",
            "analyzer": "standard"
          }
        }
      }
    }
  }
}

查询-单字段查询

match查询和term查询的区别:term查询不进行分词的分析,直接去索引内精确搜索,大小写必须匹配;match查询按照字段上定义的分词,分析后会去索引内查询;

GET /movie/_analyze
{
    "field": "title",
    "text": "steve jobs"
}

#精确匹配 相当于 where = ''
GET movie/_search
{
  "query": {
    "term": {
      "title": "Steve Zissou"
    }
  }
}

#分词后的and和or的逻辑, match 默认使用的是or
GET /movie/_search
{
    "query": {
        "match": {
            "title": "basketball with cartoom aliens"
        }
    }
}

#分词后的and和or的逻辑, match设置成and
GET /movie/_search
{
  "query": {
    "match": {
      "title": {
        "query": "basketball with cartoom aliens love",
        "operator": "and",
      }
    }
  }
}

#最小词匹配项 minimum_should_match:至少2项匹配
GET movie/_search
{
  "query": {
    "match": {
      "title": {
        "query": "basketball with cartoom aliens love",
        "operator": "or",
        "minimum_should_match": 2
      }
    }
  }
}

#短语查询 相当于 like '%x%'
GET movie/_search
{
  "query": {
    "match_phrase": {
      "title": "steve zissou"
    }
  }
}


查询-多字段查询

#多字段查询
GET movie/_search
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title", "overview"]
    }
  }
}

搜索原理

TF: token frequency, 分词在document字段(待搜索的字段)中出现的次数

IDF:inverse document frequency, 逆文档频率,代表分词在整个文档中出现的频率,取反

举报

相关推荐

0 条评论