【问题标题】:MongoDB's aggregate $search is not pulling any resultsMongoDB 聚合 $search 没有提取任何结果
【发布时间】:2020-07-26 16:28:29
【问题描述】:

所以我正在开发一个 express/mongoose/mongoDB 应用程序,该应用程序要求用户查询数据库以根据 3 个字段查找其他用户,但由于某种原因,我为测试目的制作的所有文档都没有被提取为结果。即使我使查询参数与正在搜索的字段完全匹配。我正在搜索的字段是:

  • 名字
  • 姓氏
  • 用户名

我的用户有以下模型(当然是修剪过的)。

const BlockedUser = require("./blockeduser");
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const UserSchema = new Schema({
  email: {
    type: String,
    required: [true, "Please provide a valid email"],
    unique: true,
    trim: true,
    lowercase: true
  },
  password: {
    type: String,
    minlength: 10,
    trim: true,
    select: false
  },
  username: {
    type: String,
    required: [true, "Please provide a username"],
    unique: true,
    minlength: 3,
    maxlength: 255
  },
  firstName: {
    type: String,
    required: [true, "Please provide a first name"],
    minlength: 3,
    maxlength: 255
  },
  lastName: {
    type: String,
    required: [true, "Please provide a first name"],
    minlength: 3,
    maxlength: 255
  },
  blockList: {// External collection of a list of blocked users
    type: Schema.Types.ObjectId,
    ref: 'BlockedUser'
  }
});

const User = mongoose.model("User", UserSchema);

module.exports = User;

然后在 express 应用中使用 mongoose 进行以下查询。

const mongoose = require("mongoose");
const User = require("../models/user");

router.get("/profiles", async (req, res, next) => {
  const users = await User.aggregate([
    {
      $search: {
        "text": {
          "query": req.query.q,
          "path": ["username", "firstName", "lastName"],
          "fuzzy": {}
        }
      }
    },
    {
      $match: {
        _id: {$ne: mongoose.Types.ObjectId(req.user.id)} // Makes sure the user is not pulling themselves as a result
      }
    },
    { // Populates blockList
      $lookup: {
        from: "blockedusers",
        let: {
          "theId": "$blockList"
        },
        pipeline: [
          {
            $match: {
              $expr: {
                $eq: ["$_id", "$$theId"]
              }
            }
          }
        ],
        as: "blockList"
      }
    },
    {
      $match: {
        "blockList.blockedUsers": {
          $ne: mongoose.Types.ObjectId(req.user.id) // Makes sure the user is not on the queried blocked user list
        }
      }
    },
    {
      $project: {
        _id: 0,
        email: 0
      }
    }
  ]);

  res.status(200).json({
    status: "success",
    data: users
  });
});

最后是我发送的查询 URL。

http://127.0.0.1:1337/profiles?q=willow

为了彻底起见,这是我要提取的文档。

{
  username: "Willow",
  firstName: "Jennifer",
  lastName: "Jones",
  email: "email@example.com",
  password: "examplepass1234" // This is hashed don't worry :P
}

我是否遗漏了一些使我的应用无法检索结果的事情?我也知道 $text 搜索也可用,但我目前正在免费的 MongoDB 层上测试和构建,每次尝试使用 $text 搜索时,我都会收到错误消息,提示“$text 不适用于此图集层”。很想弄清楚这一点,因为这是拥有功能原型的最后步骤之一哈哈!

感谢任何有见识的人。这对我来说意义重大!

【问题讨论】:

    标签: node.js mongodb express mongoose mongodb-atlas-search


    【解决方案1】:

    所以不久前在这里发布了一个答案,我相信用户删除了它,但他们提到了一些让我思考的东西(我认为他们的名字是 Eol,所以谢谢 Eol !!!)。他们提到设置“索引”,然后谈到在查找查询中使用 $text。从那以后,我开始使用我的猫鼬模型并将我查询的 3 个字段的索引设置为index: "text",通过注册一个新的测试用户创建了一个新文档,并且成功了!我只需要在 3 个字段上设置索引就可以了。除此之外,我确实必须在 mongoDB atlas 仪表板内“构建”我的搜索索引。

    因此,如果您遇到同样的问题,请记住在您尝试搜索的字段上设置索引。就我而言,我需要它看起来像:

    const BlockedUser = require("./blockeduser");
    const mongoose = require("mongoose");
    const Schema = mongoose.Schema;
    const UserSchema = new Schema({
      email: {
        type: String,
        required: [true, "Please provide a valid email"],
        unique: true,
        trim: true,
        lowercase: true
      },
      password: {
        type: String,
        minlength: 10,
        trim: true,
        select: false
      },
      username: {
        type: String,
        required: [true, "Please provide a username"],
        unique: true,
        minlength: 3,
        maxlength: 255,
        index: "text" // <----------- MAKE SURE to add this to allow you to search this field!
      },
      firstName: {
        type: String,
        required: [true, "Please provide a first name"],
        minlength: 3,
        maxlength: 255,
        index: "text" // <----------- MAKE SURE to add this to allow you to search this field!
      },
      lastName: {
        type: String,
        required: [true, "Please provide a first name"],
        minlength: 3,
        maxlength: 255,
        index: "text" // <----------- MAKE SURE to add this to allow you to search this field!
      },
      blockList: {// External collection of a list of blocked users
        type: Schema.Types.ObjectId,
        ref: 'BlockedUser'
      }
    });
    

    查询被单独留下,并且运行良好。

    鉴于我(还)对 MongoDB 了解不多,我猜您需要使用索引字段以某种方式“分类”您将使用某些设置的 MongoDB 类别查询的字段。同样,这是我可以解释我所知道的东西的最佳方式,但希望这对未来的人有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多