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

Elasticsearch中实现特定排序逻辑及接入用户推荐的技术咨询

解决方案:ES接入用户推荐数据+三阶段排序实现

一、用户推荐数据的ES接入方案

方案1:独立推荐索引(推荐大规模场景)

创建单独的索引user_recommendations,字段设计如下:

  • user_id:keyword类型,用于精准匹配用户
  • product_id:keyword类型,关联商品索引的商品ID
  • recommend_score:float类型,存储0-1的推荐值

同步逻辑:推荐系统生成用户推荐结果后,通过ES Bulk API批量执行upsert操作(以user_id+product_id为唯一键),确保数据实时更新且无重复。

方案2:商品索引新增嵌套推荐字段(仅适合小用户量场景)

在现有商品索引中添加嵌套类型字段user_recommendations,结构示例:

"user_recommendations": {
  "type": "nested",
  "properties": {
    "user_id": {"type": "keyword"},
    "recommend_score": {"type": "float"}
  }
}

同步逻辑:推荐结果更新时,通过ES Update API针对目标商品ID,更新指定user_id对应的推荐分数。但用户规模较大时,会导致商品文档体积急剧膨胀,不建议生产环境大规模使用。

二、三阶段排序逻辑的ES实现

核心思路是通过优先级排序+查询过滤拆分三个结果段,同时避免商品重复展示。

方式1:Bool查询+Boost优先级区分

通过给不同阶段的查询设置不同的Boost值,让第一阶段结果得分最高,第二阶段次之,第三阶段最低,再结合字段排序实现内部排序:

GET /products/_search
{
  "query": {
    "bool": {
      "should": [
        // 第一阶段:热度>A的热门商品,Boost设为最高
        {
          "range": {
            "popularity": {
              "gt": 80 // 替换为实际阈值A
            }
          }
        },
        // 第二阶段:用户推荐商品(排除已在第一阶段的商品),Boost次之
        {
          "bool": {
            "must": [
              {
                "terms": {
                  "product_id": ["prod_001", "prod_002"] // 从user_recommendations查询得到的当前用户推荐商品ID列表
                }
              },
              {
                "range": {
                  "popularity": {
                    "lte": 80
                  }
                }
              }
            ]
          }
        },
        // 第三阶段:剩余商品(排除前两个阶段),Boost最低
        {
          "bool": {
            "must_not": [
              {
                "range": {
                  "popularity": {
                    "gt": 80
                  }
                }
              },
              {
                "terms": {
                  "product_id": ["prod_001", "prod_002"]
                }
              }
            ]
          }
        }
      ],
      "minimum_should_match": 1
    }
  },
  "sort": [
    {"_score": {"order": "desc"}}, // 按查询得分区分三个阶段优先级
    {"popularity": {"order": "desc", "missing": "_last"}}, // 第一、三阶段内部按热度降序
    {"recommend_score": {"order": "desc", "missing": "_last"}} // 第二阶段内部按推荐值降序
  ]
}

方式2:脚本字段生成排序优先级

通过脚本给不同阶段的商品分配优先级数值,直接按优先级排序,内部再按对应字段排序:

GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "sort_priority": {
      "script": {
        "source": """
          def pop = doc['popularity'].value;
          def isRec = params.recIds.contains(doc['product_id'].value);
          if (pop > params.threshold) {
            return 3; // 第一阶段优先级最高
          } else if (isRec) {
            return 2; // 第二阶段次之
          } else {
            return 1; // 第三阶段最低
          }
        """,
        "params": {
          "threshold": 80, // 替换为实际热度阈值A
          "recIds": ["prod_001", "prod_002"] // 当前用户的推荐商品ID列表
        }
      }
    }
  },
  "sort": [
    {"sort_priority": {"order": "desc"}},
    {"popularity": {"order": "desc"}},
    {"recommend_score": {"order": "desc", "missing": "_last"}}
  ]
}

关键注意事项

  1. 推荐商品ID列表需提前从user_recommendations索引查询获取,再带入商品查询;应用层先获取推荐列表再构造查询是最高效的方式。
  2. 必须通过过滤条件排除不同阶段的重复商品,避免同一商品多次展示。
  3. 如果使用嵌套字段存储推荐数据,需结合nested查询获取对应用户的推荐分数,但性能远低于独立索引方案。

内容的提问来源于stack exchange,提问作者Александр Корхов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 12:12:42