MST
星途 面试题库

面试题:ElasticSearch集成Lucene实现复杂搜索功能

假设在一个电商系统中,需要实现基于商品描述的全文搜索、多字段过滤以及相关性排序等复杂功能。请详细说明如何利用ElasticSearch集成Lucene来实现这些功能,包括涉及到的Lucene特性及ElasticSearch的配置和API调用。
25.8万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试

1. 利用Lucene特性实现功能

  • 全文搜索
    • Lucene使用倒排索引结构,将文档中的每个词(term)映射到包含该词的文档列表及词在文档中的位置等信息。在电商系统商品描述的全文搜索中,Lucene会对商品描述文本进行分词,将每个词构建到倒排索引中。例如,商品描述“时尚女士连衣裙,夏季新款”,分词后如“时尚”“女士”“连衣裙”“夏季”“新款”等词都会进入倒排索引。搜索时,Lucene根据用户输入的关键词在倒排索引中查找匹配的文档,实现快速全文检索。
    • 模糊搜索:Lucene支持模糊查询,通过编辑距离(如Levenshtein距离)来匹配与查询词相似的词。比如用户输入“dress”,可能匹配到“dresses”等相似词,以提高搜索召回率。
  • 多字段过滤
    • Lucene的Filter机制可以对文档的多个字段进行过滤。在电商系统中,假设商品有“类别”“品牌”“价格范围”等字段。可以为每个字段构建相应的Filter,如构建一个“类别Filter”用于筛选特定类别的商品(如“服装”类别),“品牌Filter”筛选特定品牌商品(如“Nike”品牌),“价格范围Filter”筛选价格在一定区间的商品(如100 - 500元)。然后将这些Filter组合使用,实现多字段过滤,只返回符合所有过滤条件的商品文档。
  • 相关性排序
    • Lucene的评分(Scoring)机制用于衡量文档与查询的相关性。它考虑多个因素,如词频(Term Frequency, TF),即查询词在文档中出现的频率,频率越高相关性可能越高;逆文档频率(Inverse Document Frequency, IDF),反映了词在整个文档集合中的稀有程度,稀有词对相关性贡献更大。例如,在商品描述中,“苹果手机”的“苹果”词频较高且“手机”词相对普遍,结合IDF计算后得出该商品文档与“苹果手机”查询的相关性分数。还可以结合文档长度归一化等因素,综合计算出最终的相关性分数,用于对搜索结果进行排序。

2. ElasticSearch配置

  • 安装ElasticSearch
    • 从ElasticSearch官方网站下载适合系统的安装包,如在Linux系统下,解压下载的.tar.gz文件。例如,下载elasticsearch-7.10.2.tar.gz,解压命令为tar -zxvf elasticsearch-7.10.2.tar.gz
    • 进入解压后的目录cd elasticsearch - 7.10.2
  • 配置索引
    • 创建索引配置文件,例如product_index.json,用于定义商品索引的结构和映射。示例内容如下:
{
    "mappings": {
        "properties": {
            "product_description": {
                "type": "text",
                "analyzer": "standard"
            },
            "category": {
                "type": "keyword"
            },
            "brand": {
                "type": "keyword"
            },
            "price": {
                "type": "float"
            }
        }
    }
}
- 上述配置中,`product_description`字段用于商品描述,采用标准分词器;`category`和`brand`字段为关键词类型,适合用于过滤;`price`字段为浮点数类型用于价格。
- 使用`curl`命令创建索引:`curl -X PUT "http://localhost:9200/product_index" -H 'Content-Type: application/json' -d @product_index.json`。

3. ElasticSearch API调用

  • 全文搜索
    • 使用_search API进行全文搜索。例如,搜索商品描述中包含“时尚连衣裙”的商品:
curl -X GET "http://localhost:9200/product_index/_search" -H 'Content-Type: application/json' -d'
{
    "query": {
        "match": {
            "product_description": "时尚连衣裙"
        }
    }
}'
- `match`查询是全文搜索常用方式,ElasticSearch会对查询词进行分词处理,在`product_description`字段的倒排索引中查找匹配文档。
  • 多字段过滤
    • 结合bool查询和filter子句实现多字段过滤。假设要筛选“服装”类别且“Nike”品牌的商品:
curl -X GET "http://localhost:9200/product_index/_search" -H 'Content-Type: application/json' -d'
{
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                        "category": "服装"
                    }
                },
                {
                    "term": {
                        "brand": "Nike"
                    }
                }
            ]
        }
    }
}'
- `bool`查询的`filter`子句会应用多个`term`查询进行过滤,只返回满足所有过滤条件的商品文档。
  • 相关性排序
    • ElasticSearch默认会根据Lucene的评分机制进行相关性排序。但也可以通过sort参数进行自定义排序。例如,除了相关性排序外,还希望按照价格从高到低排序:
curl -X GET "http://localhost:9200/product_index/_search" -H 'Content-Type: application/json' -d'
{
    "query": {
        "match": {
            "product_description": "运动装备"
        }
    },
    "sort": [
        {
            "price": {
                "order": "desc"
            }
        }
    ]
}'
- 上述请求先根据相关性对“运动装备”搜索结果排序,再按照价格从高到低排序。