You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

大规模爬虫文档的Elasticsearch高效搜索方案及查询选型咨询

最优搜索方案设计与疑问解答

针对你的300万+文档规模、加权排序+域名去重的搜索需求,以下是具体实现方案和疑问解答:

核心方案:function_score查询+聚合去重

结合Elasticsearch的function_score实现加权评分,再通过terms聚合完成域名去重,是最适合当前场景的高效方案,具体逻辑如下:

1. 先优化映射(必做调整)

当前domain和url是keyword类型,仅支持精确匹配,无法满足关键词/句子的模糊搜索需求。需给这两个字段添加text子字段:

PUT /crawled_data/_mapping
{
  "properties": {
    "domain": {
      "type": "keyword",
      "fields": {
        "text": {
          "type": "text",
          "analyzer": "standard"
        }
      }
    },
    "url": {
      "type": "keyword",
      "fields": {
        "text": {
          "type": "text",
          "analyzer": "standard"
        }
      }
    }
  }
}

2. 最终搜索DSL示例

POST /crawled_data/_search
{
  "size": 0, // 无需返回原始文档,仅取聚合结果
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "should": [
            {"match": {"domain.text": {"query": "你的搜索关键词", "operator": "and"}}},
            {"match": {"url.text": {"query": "你的搜索关键词", "operator": "and"}}},
            {
              "nested": {
                "path": "headers",
                "query": {
                  "bool": {
                    "should": [
                      {"match": {"headers.h1": "你的搜索关键词"}},
                      {"match": {"headers.h2": "你的搜索关键词"}},
                      {"match": {"headers.h3": "你的搜索关键词"}},
                      {"match": {"headers.h4": "你的搜索关键词"}},
                      {"match": {"headers.h5": "你的搜索关键词"}},
                      {"match": {"headers.h6": "你的搜索关键词"}}
                    ]
                  }
                }
              }
            },
            {"match": {"content": {"query": "你的搜索关键词", "operator": "and"}}}
          ],
          "minimum_should_match": 1 // 至少匹配一个字段
        }
      },
      "functions": [
        // 按权重优先级设置加分规则
        {"filter": {"match": {"domain.text": "你的搜索关键词"}}, "weight": 10},
        {"filter": {"match": {"url.text": "你的搜索关键词"}}, "weight": 7},
        {
          "filter": {
            "nested": {
              "path": "headers",
              "query": {
                "bool": {
                  "should": [
                    {"match": {"headers.h1": "你的搜索关键词"}},
                    {"match": {"headers.h2": "你的搜索关键词"}},
                    {"match": {"headers.h3": "你的搜索关键词"}},
                    {"match": {"headers.h4": "你的搜索关键词"}},
                    {"match": {"headers.h5": "你的搜索关键词"}},
                    {"match": {"headers.h6": "你的搜索关键词"}}
                  ]
                }
              }
            }
          },
          "weight": 5
        },
        {"filter": {"match": {"content": "你的搜索关键词"}}, "weight": 2}
      ],
      "score_mode": "sum", // 多个匹配项的权重累加
      "boost_mode": "sum" // 基础得分+权重得分
    }
  },
  "aggs": {
    "unique_domains": {
      "terms": {
        "field": "domain",
        "size": 100, // 返回前100个达标域名
        "order": {"max_score": "desc"} // 按域名下的最高文档得分排序
      },
      "aggs": {
        "max_score": {"max": {"script": "_score"}} // 取该域名下得分最高的文档分数作为排序依据
      }
    }
  },
  "min_score": 1 // 过滤低分文档,减少聚合计算量
}

疑问解答

1. function_score是否会导致300万文档资源占用过高?

不会。function_score仅在bool查询匹配到的文档上计算得分,而非全量扫描300万文档。通过设置min_score、operator: and等参数,可以进一步缩小匹配范围,控制资源消耗。只要你的ES集群配置合理(分片数3-5个),完全能支撑这个规模的查询。

2. 是否更适合用高级聚合查询?

聚合是实现域名去重的核心手段,必须结合查询使用——先通过function_score计算加权得分,再用terms聚合按域名分组并排序。单独用聚合无法实现加权评分逻辑,二者是互补关系。

3. 是否需要自定义微服务处理评分?

没必要。ES的function_score已经能精准实现多字段加权逻辑,且是分布式计算,性能远优于将大量文档拉取到微服务端处理。自定义评分会增加网络传输和计算开销,反而降低效率。

额外优化建议

  • 开启ES查询缓存,对重复搜索关键词快速返回结果;
  • 根据集群节点数调整索引分片数(建议3-5个),提升并行处理能力;
  • 若搜索需求以精确关键词为主,可给text字段添加keyword子字段的反向设计,平衡模糊搜索和精确匹配性能。

内容的提问来源于stack exchange,提问作者Casper Karlsson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:55:55