ES的记录

本文分享了一次解决搜索引擎中索引设计和分词器配置问题的经验,详细介绍了使用ik分词器与拼音分词相结合的方法,并给出了具体的Elasticsearch设置及查询案例。

昨天做了好久,一直查不出来,后来发现是我的索引设计和分词器设计有问题。

创建索引

  "settings": {
    "analysis": {
      "analyzer": {
        "my_pinyin": {
          "tokenizer": "ik_smart",
          "filter": [
            "pinyin"
          ]
        }
      },
      "filter": {
        "pinyin": {
          "type": "pinyin",
          "keep_full_pinyin": true,
          "keep_joined_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "remove_duplicated_term": true
        }
      }
    }

这是把ik分词器当做主要分词,拼音分词次要。

 "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "title": {
        "type": "completion",
        "analyzer": "my_pinyin"
      },
      "name": {
        "type": "text",
        "analyzer": "my_pinyin"
      },
      
      "cover_bucket":{
        "type": "keyword"
      },
       "cover_object":{
        "type": "keyword"
      }
    }
  }

一开始写错了,除了定义了一个analyzer,还另外写了一个search-analyzer,所以就不对了,多此一举。

相关查询

1.matchQuery

SearchSourceBuilder sourceBuilder= new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchQuery("name","手机"))

2.termQuey

SearchSourceBuilder sourceBuilder= new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("name","手机"))

上述两种搜索都是基本搜索,但是前者是知道有分词器的存在,后者是不知道分词器的存在(适合keyword,datetime,int类型)

3.排序搜索

 sourceBuilder.sort(searchParamDTO.getSortBy(),searchParamDTO.getDesc()? SortOrder.ASC: SortOrder.DESC);

4.高亮搜索

  HighlightBuilder highlightBuilder = new HighlightBuilder();            
highlightBuilder.field(SearchConstants.DEFAULT_SEARCH_FIELD).preTags(SearchConstants.DEFAULT_PRE_TAG).postTags(SearchConstants.DEFAULT_POST_TAG);
 sourceBuilder.highlighter(highlightBuilder);

5.范围搜索

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();  
boolQueryBuilder.filter(QueryBuilders.rangeQuery(key).gt(first).lt(end));

  大于小于等于

6.模糊搜索

  FuzzyQueryBuilder fuzzyQuery = new FuzzyQueryBuilder("name","手机");
  fuzzyQuery.fuzziness(Fuzziness.TWO);

默认模糊搜索的度最大是2。

7.分页

 sourceBuilder.from(searchParamDTO.getFrom());//分页
 sourceBuilder.size(searchParamDTO.getSize());

看了还有聚合搜索什么的 我得好好看看了。886

在 Elasticsearch 中,可以通过脚本字段和聚合来根据搜索记录的搜索次数和搜索时间计算热度值。以下是具体的实现步骤和示例代码: ### 数据准备 假设搜索记录的文档结构如下: ```json { "search_term": "example term", "search_count": 10, "search_time": "2024-01-01T12:00:00Z" } ``` ### 计算热度值的方法 可以使用 Elasticsearch 的脚本字段和聚合来计算热度值。热度值的计算可以考虑搜索次数和搜索时间的权重,例如,近期的搜索记录给予更高的权重。 #### 示例代码 ```python from elasticsearch import Elasticsearch # 连接到 Elasticsearch es = Elasticsearch([{'host': 'localhost', 'port': 9200}]) # 定义查询和聚合 query = { "size": 0, "aggs": { "hot_search_terms": { "terms": { "field": "search_term.keyword" }, "aggs": { "total_search_count": { "sum": { "field": "search_count" } }, "latest_search_time": { "max": { "field": "search_time" } }, "heat_score": { "bucket_script": { "buckets_path": { "count": "total_search_count", "time": "latest_search_time" }, "script": "params.count * Math.exp(-(params.now - params.time) / (1000 * 60 * 60 * 24))", "params": { "now": int(es.info()['process']['start_time_in_millis']) } } } } } } } # 执行查询 response = es.search(index="search_records", body=query) # 输出结果 for bucket in response['aggregations']['hot_search_terms']['buckets']: print(f"Search Term: {bucket['key']}, Heat Score: {bucket['heat_score']['value']}") ``` ### 代码解释 1. **连接到 Elasticsearch**:使用 `Elasticsearch` 类连接到 Elasticsearch 集群。 2. **定义查询和聚合**: - `terms` 聚合按搜索词分组。 - `sum` 聚合计算每个搜索词的总搜索次数。 - `max` 聚合获取每个搜索词的最新搜索时间。 - `bucket_script` 聚合根据搜索次数和搜索时间计算热度值。 3. **执行查询**:使用 `search` 方法执行查询,并获取结果。 4. **输出结果**:遍历聚合结果,输出每个搜索词的热度值。 ### 注意事项 - 热度值的计算方法可以根据实际需求进行调整,例如,可以调整时间衰减的系数。 - 确保 Elasticsearch 集群的时间和脚本中的时间戳一致。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值