【问题标题】:MongoDB using $text with other query paramsMongoDB 使用 $text 和其他查询参数
【发布时间】:2020-07-01 19:45:55
【问题描述】:

我正在尝试搜索主题、名称和关键字。我希望首先搜索文本,如果找到包含这些单词的帖子以找到用户,然后通过 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,
              },
            },

【问题讨论】:

  • 你的问题是什么?
  • 如何按关键字搜索。让我举个例子,如果我们在帖子 N “Lorem ipsum dolor sit amet”中有以下文字,如果我有以下关键字“ipsum sit”或“ipsum Lorem”来返回这篇文章。
  • $text 采用字符串参数,而不是正则表达式。您是否尝试过 $text 文档中的示例?
  • 是的,我试过了,但也许我做错了什么。这就是为什么在这里提出问题。有什么想法可能是问题所在?
  • 文本索引是如何创建的?

标签: mongodb aggregation-framework


【解决方案1】:

我认为问题出在这部分

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

可视化为

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

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


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

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

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

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

/lorem|ipsum/gmi

| 匹配 loremipsum

你可以看到工作的here

【讨论】:

  • 很棒的答案!这就是我一直在寻找的。顺便说一句,我也在考虑同样的事情,但不确定到底发生了什么。所以你认为应该是怎样的。 { text: { $regex: /`${postWords}`/gmi } } 之类的东西?它还给我以下错误Missing expected field "$search"
  • 你需要用|替换space,你可以使用/${postWords.replace(" ", "|")}/gmi之类的东西
  • 我已经处理好了!谢谢,但仍然给出这个错误Missing expected field "$search"
  • $match: {$text: {$search: postWords,$caseSensitive: false,},} 我正在使用这个,现在唯一的问题是只有在第一个单词存在时才返回。示例:如果我在数据库中有以下文本“你好,我的朋友”,它将与“我|你好”和“你好|朋友”一起使用,但是当我尝试删除第一个单词时什么都不返回。
  • 对于$search,您必须提供空格分隔的字符串,例如"hello friend";对于$regex,您必须在/hello|friend/等单词之间使用管道
猜你喜欢
  • 1970-01-01
  • 2013-12-28
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 2020-05-06
  • 2021-06-07
  • 2021-08-22
相关资源
最近更新 更多