首页 > 解决方案 > MongoDB 使用 $text 和其他查询参数

问题描述

我正在尝试搜索主题、名称和关键字。我希望首先搜索文本,如果找到包含这些单词的帖子以找到用户,然后通过 user.name 和主题进行查询,但是当我使用它时:

const posts = await Post.aggregate([
      {
        $match: {
          $text: {
            $search: postWords ? `${postWords}` : /.*/,
            $caseSensitive: false,
          },
        },
      },
      {
        $lookup: {
          from: "users",
          localField: "user",
          foreignField: "_id",
          as: "user",
        },
      },
      {
        $unwind: "$user",
      },
      {
        $match: {
          $and: [
            {
              topic: {
                $regex: postTopic ? postTopic : /.*/,
                $options: "i",
                $exists: true,
              },
            },
            {
              "user.name": {
                $regex: postName ? postName : /.*/,
                $options: "i",
                $exists: true,
              },
            },
            { text: { $regex: postWords ? postWords : /.*/, $options: "i" } },
          ],
        },
      },
      {
        $skip: req.params.page ? (req.params.page - 1) * 10 : 0,
      },
      {
        $limit: 11,
      },
      {
        $project: {
          "user.password": 0,
          "user.active": 0,
          "user.email": 0,
          "user.temporaryToken": 0,
        },
      },
    ]);

假设文本是 lorem ipsum,我尝试使用“ipsum lorem”之类的关键字搜索不起作用,但使用“lorem ipsum”可以。postWords 是一个字符串,单词用空格分隔(如果需要,我也可以将其设为数组)。

编辑1:

$and: [
            {
              topic: {
                $regex: postTopic ? postTopic : /.*/,
                $options: "i",
                $exists: true,
              },
            },
            {
              text: {
                $regex: `/${postWords}/g`,
                $options: "i",
              },
            },
            {
              "user.name": {
                $regex: postName ? postName : /.*/,
                $options: "i",
                $exists: true,
              },
            },

标签: mongodbaggregation-framework

解决方案


我认为问题出在这部分

{ text: { $regex: postWords ? postWords : /.*/, $options: "i" } }

它可以被可视化为

{ text: { $regex: /lorem ipsum/i } }

在它匹配并给出输出的情况下,是因为您lorem ipsum与文档中的文本完全匹配,lorem ipsum所以它匹配。您可以在此处查看示例


但是当你指定ipsum lorem查询变成这个

{ text: { $regex: /ipsum lorem/i } }

lorem ipsum您可以清楚地看到此正则表达式与您文档中的文本不匹配。你可以在这里看到

所以我们现在需要做的是在这两种情况下构造一个匹配你的文本 lorem ipsum 的正则表达式

/lorem|ipsum/gmi

|匹配loremipsum

你可以在这里看到工作


推荐阅读