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

在Atlas Search中同时搜索嵌入字段与非嵌入字段的问题

解决方案

问题出在你的$search阶段仅针对嵌入文档todos进行查询,没有包含根级的title字段。需要调整$search的结构,用compound操作符同时包含对title和todos.todo的搜索逻辑。

修改后的聚合管道中$search部分核心调整如下:

{
  $search: {
    index: 'search_todos',
    compound: {
      should: [
        // 新增针对title字段的搜索逻辑
        {
          text: {
            query: search,
            path: 'title',
            fuzzy: {
              maxEdits: 1,
              maxExpansions: 10,
            },
          },
        },
        {
          phrase: {
            query: search,
            path: 'title',
            slop: 2,
          },
        },
        // 保留原有的嵌入文档todos查询逻辑
        {
          embeddedDocument: {
            path: 'todos',
            operator: {
              compound: {
                must: [
                  {
                    text: {
                      query: search,
                      path: ['todos.todo'],
                      fuzzy: {
                        maxEdits: 1,
                        maxExpansions: 10,
                      },
                    },
                  },
                ],
                should: [
                  {
                    phrase: {
                      query: search,
                      path: ['todos.todo'],
                      slop: 2,
                    },
                  },
                ],
              },
            },
          },
        },
      ],
    },
    count: {
      type: 'total',
    },
  },
}

关键修改说明:

  • 外层改用compound操作符,通过should数组同时容纳两类搜索条件:
    1. 新增与todos.todo逻辑一致的title字段查询(text模糊匹配+phrase短语匹配)
    2. 将原有的嵌入文档查询作为should数组的一个元素保留
  • should规则表示只要匹配任意一个条件,文档就会被返回,且会根据匹配条件的数量计算相关性得分

完整的聚合管道代码:

const searchtodos = await this.todoModel.aggregate([
  {
    $search: {
      index: 'search_todos',
      compound: {
        should: [
          {
            text: {
              query: search,
              path: 'title',
              fuzzy: {
                maxEdits: 1,
                maxExpansions: 10,
              },
            },
          },
          {
            phrase: {
              query: search,
              path: 'title',
              slop: 2,
            },
          },
          {
            embeddedDocument: {
              path: 'todos',
              operator: {
                compound: {
                  must: [
                    {
                      text: {
                        query: search,
                        path: ['todos.todo'],
                        fuzzy: {
                          maxEdits: 1,
                          maxExpansions: 10,
                        },
                      },
                    },
                  ],
                  should: [
                    {
                      phrase: {
                        query: search,
                        path: ['todos.todo'],
                        slop: 2,
                      },
                    },
                  ],
                },
              },
            },
          },
        ],
      },
      count: {
        type: 'total',
      },
    },
  },
  {
    $match: query,
  },
  {
    $lookup: {
      from: 'userentities',
      localField: 'userId',
      foreignField: '_id',
      as: 'userData',
    },
  },
  {
    $unwind: '$userData',
  },
  {
    $project: todoProject,
  },
  {
    $facet: {
      totalCount: [{ $count: 'count' }],
      documents: [
        {
          $skip: (page - 1) * limit,
        },
        {
          $limit: limit,
        },
      ],
    },
  },
]);

修改后,搜索"Demo"会匹配title字段,搜索"football"会匹配todos.todo字段,两种场景都能返回对应文档。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 02:13:12