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

如何在Mongoose中实现带相关性排序的部分文本搜索?

问题

我用Mongoose查询MongoDB,想要按相关性从高到低返回结果。目前的代码能实现多字段搜索并按textScore排序,但只能匹配完整单词——比如搜"example"能找到包含该词的条目,但搜"examp"就找不到。

我知道用正则可以实现部分搜索,但没法用textScore排序。因为数据量大还要分页,不能查完再排序。有没有办法同时实现部分文本搜索和相关性排序?

当前代码

let searchValue = "examp";
let matchingItems = await Items.find(
  {
    $text: {
      $search: searchValue,
    }
  },
  {
    score: {
      $meta: "textScore"
    }
  },
  {
    sort: {
      score: {
        $meta: "textScore"
      }
    }
  }
);

示例数据库数据

[
  {name: "dignissim", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit."},
  {name: "Fusce eget.", description: "Nullam malesuada ex sit amet diam ultrices"},
  {name: "Duis nec", description: "Proin at dolor at est porta aliquet. Proin viverra imperdiet orci, a ornare tortor"},
  {name: "Mauris.", description: "Aenean tristique ante et eros porttitor, ut sodales ipsum pulvinar."},
  {name: "Pellentesque", description: "Nam dignissim ipsum a elit fermentum"},
  {name: "facilisis augue", description: "Etiam sit amet dolor sed sapien rutrum sodales."},
  {name: "erat suscipit", description: "this is an example description"},
]

Schema定义

const mongoose = require("mongoose");

const schema = new mongoose.Schema({
    name: String,
    description: String
});

schema.index({ name: "text", description: "text" });

const Items = mongoose.model("Item", schema);

解决方案

方法1:MongoDB Atlas Search(推荐,云部署场景)

如果你的MongoDB部署在Atlas上,Atlas Search的autocomplete索引完美适配前缀/部分搜索+相关性排序需求:

  1. 创建Atlas Search索引
    在Atlas控制台为items集合创建索引(可通过可视化界面或命令行):
{
  "mappings": {
    "dynamic": false,
    "fields": {
      "name": [
        {
          "type": "autocomplete",
          "tokenization": "edgeGram",
          "minGrams": 2,
          "maxGrams": 10
        },
        { "type": "string" }
      ],
      "description": [
        {
          "type": "autocomplete",
          "tokenization": "edgeGram",
          "minGrams": 2,
          "maxGrams": 10
        },
        { "type": "string" }
      ]
    }
  }
}
  1. Mongoose查询代码
    用$search操作符执行搜索并获取相关性分数:
let searchValue = "examp";
let matchingItems = await Items.aggregate([
  {
    $search: {
      autocomplete: {
        query: searchValue,
        path: ["name", "description"],
        score: { boost: { value: 5 } } // 可自定义字段权重
      }
    }
  },
  { $addFields: { score: { $meta: "searchScore" } } },
  { $sort: { score: -1 } },
  // 分页配置
  { $skip: 0 },
  { $limit: 10 }
]);

方法2:正则匹配+自定义相关性评分(自建MongoDB场景)

无法使用Atlas Search时,可通过正则匹配结合$expr计算自定义分数,实现近似相关性排序:

思路:给不同匹配场景设置权重(比如前缀匹配权重高于包含匹配),按总分排序:

let searchValue = "examp";
const regex = new RegExp(searchValue, "i"); // 不区分大小写

let matchingItems = await Items.aggregate([
  {
    $match: {
      $or: [
        { name: regex },
        { description: regex }
      ]
    }
  },
  {
    $addFields: {
      score: {
        $sum: [
          // name前缀匹配,权重5分
          { $cond: [{ $regexMatch: { input: "$name", regex: new RegExp(`^${searchValue}`, "i") } }, 5, 0] },
          // name包含匹配,权重3分
          { $cond: [{ $regexMatch: { input: "$name", regex } }, 3, 0] },
          // description前缀匹配,权重4分
          { $cond: [{ $regexMatch: { input: "$description", regex: new RegExp(`^${searchValue}`, "i") } }, 4, 0] },
          // description包含匹配,权重2分
          { $cond: [{ $regexMatch: { input: "$description", regex } }, 2, 0] }
        ]
      }
    }
  },
  { $sort: { score: -1 } },
  // 分页配置
  { $skip: 0 },
  { $limit: 10 }
]);

性能优化:给name和description创建单字段索引,避免大数据量下查询缓慢:

schema.index({ name: 1 });
schema.index({ description: 1 });

方法3:文本索引+通配符查询(仅支持单词前缀匹配)

MongoDB文本索引支持后缀通配符(examp*),但仅能匹配单词开头,局限性较大:

let searchValue = "examp";
let matchingItems = await Items.find(
  {
    $text: {
      $search: `"${searchValue}*"` // 双引号包裹+*,匹配以examp开头的单词
    }
  },
  { score: { $meta: "textScore" } },
  {
    sort: { score: { $meta: "textScore" } },
    skip: 0,
    limit: 10
  }
);

总结

  • 云部署优先选Atlas Search,功能完善、性能最优;
  • 自建MongoDB用正则+自定义评分方案,需自行维护权重逻辑;
  • 文本索引通配符方案仅适合单词前缀匹配的特定场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:30:44