【问题标题】:Javascript/Node array returns [object object] after spread operationJavascript/Node数组在展开操作后返回[object object]
【发布时间】:2022-01-16 05:39:56
【问题描述】:

我正在开发一个类似于 Tinder 的约会应用程序,现在,我正在使用 node-express-mongodb-mongoose 服务器,但我遇到了问题。问题是,当应用程序加载时,在主页中,我想获取所有配置文件,不包括我的配置文件和我通过的配置文件(不喜欢)。下面是该函数在节点中的路由:

用户架构:

const userSchema = new mongoose.Schema({
    email: {
        type: 'string',
        unique: [true, 'Email ID already present.'],
        required: true,
    },
    password: {
        type: 'string',
        required: true,
        minlength: 4,
    },
    displayName: {
        type: 'string',
        required: false,
        default: '',
    },
    photoURL: {
        type: 'string',
        required: false,
        default: '',
    },
    job: {
        type: 'string',
        required: false,
        default: '',
    },
    age: {
        type: 'number',
        required: false,
        default: null,
    },
    passes: {
        type: 'Array',
        required: false,
    },
    likes: {
        type: 'Array',
        required: false,
    },
    matches: {
        type: 'Array',
        required: false,
    }
  }
);

mongoose.model('User', userSchema);

获取配置文件路由:

const id = req.user._id;
    try {
        const currentUser = await User.findById({_id: id}); // gets the current user
        const passes = currentUser.passes; // gets the passed/disliked profiles (array of objects)
        const users = await User.find(); // gets all the registered users from db
        console.log(passes);
        const allUsers = [...passes, ...users]; // combining the 2 arrays 
        console.log('ALL USERS: ' + allUsers);
        const usersAfterFilter = allUsers.filter(
            (user) => user._id.toString() !== id.toString() // finally filtering because I want to fetch all the profiles excluding mine and the ones' which I have passed.
        );
        console.log('ALL USERS AFTER FILTER: ' + usersAfterFilter);
        res.send({'response': 'success', 'data': usersAfterFilter});
    } catch (error) {
        console.log(error.message);
        return res.status(422).send({response : error.message});
    }

以下是日志输出:

[
  [
    {
      _id: new ObjectId("612131375a7fd116969e298c"),
      email: '',
      password: '',
      displayName: 'Yolo',
      photoURL: '',
      job: 'CEO of World',
      age: 22,
      passes: [],
      likes: [],
      matches: [],
      createdAt: 2021-12-12T10:38:47.967Z,
      updatedAt: 2021-12-12T10:39:14.943Z,
      __v: 0
    }
  ]
]
ALL USERS: [object Object],{
  _id: new ObjectId("612131375a7fd116969e298c"),
  email: '',
  password: '',
  displayName: 'Yolo',
  photoURL: '',
  job: 'CEO of World',
  age: 22,
  passes: [],
  likes: [],
  matches: [],
  createdAt: 2021-12-12T10:38:47.967Z,
  updatedAt: 2021-12-12T10:39:14.943Z,
  __v: 0
},{
  _id: new ObjectId("61b5d2395a7fd12347ae2994"),
  email: '',
  password: '',
  displayName: 'your actor',
  photoURL: '',
  job: 'Actor',
  age: 25,
  passes: [ [ [Object] ] ],
  likes: [],
  matches: [],
  createdAt: 2021-12-12T10:39:46.347Z,
  updatedAt: 2021-12-12T10:41:36.627Z,
  __v: 0
}
Cannot read properties of undefined (reading 'toString')

如您所见,当我将两个数组组合用于过滤目的时,...passes 转换为 [object Object],因此破坏了过滤的目的,因为我无法再根据 id 进行比较。

如果有人可以在这里帮助我,我将不胜感激!

【问题讨论】:

  • 不是... 这样做,而是您在console.log 中进行的字符串连接。 'ALL USERS: ' + allUsersallUsers 转换为字符串,然后将其附加到"ALL USERS: ",并将其传递给console.log。 (我很惊讶地看到 users 对象似乎有特殊的 toString 处理,但 passes 对象显然没有,所以它们得到默认值,这导致 "[object Object]"。)正确记录对象,将它们记录为自己的参数:console.log("ALL USERS:", allusers);.
  • 但是:与其使用console.log 手电筒在黑暗中四处游荡,不如使用IDE 中内置的调试器打开灯。在您希望调试器停止的语句上设置断点,运行代码,当调试器在断点处停止时,查看变量的值。
  • @TJCrowder 感谢您提供宝贵的反馈,我尝试调试并发现不知何故,每当我传递一个用户时,我认为它会将一个对象推入数组中,passes: [ [Array] ], 我没有不知道为什么要这样做,控制台中也没有错误,根据我的User 架构,它应该可以正常工作...

标签: javascript node.js mongodb express mongoose


【解决方案1】:

...当应用程序加载时,在主页中,我想获取所有配置文件 不包括我的和我通过的(不喜欢的)。

以下演示了如何获得所需的数据。假设集合 users 中有一些文档,以下从 mongo shell 运行。

示例文档:

{ _id: 1, passes: [ 3, 4, 5 ] }, { _id: 2 }, { _id: 3 }, { _id: 4 }, { _id: 5 }, { _id: 9 }

请注意,当前用户使用_id: 1passes: [ 3, 4, 5 ]。输出将是 ID:[ 2, 9 ]

查询:

您可以使用以下任何一种方法来获得所需的结果。 第一方式:

var currentUser = db.users.findOne({ _id: 1 });
var passedUsers = currentUser.passes;
var allUsers = db.users.find().toArray();
passedUsers.push(currentUser._id);
allUsers.filter(user => (passedUsers.findIndex(passedUser => user._id == passedUser)) == -1)

输出:[ { "_id" : 2 }, { "_id" : 9 } ]


第二种方法:

var currentUser = db.users.findOne({ _id: 1 });
var passedUsers = currentUser.passes;
passedUsers.push(currentUser._id);
db.users.find( { _id: { $nin: passedUsers }} ).toArray();

第三种方式,这使用单个聚合查询:

db.users.aggregate([
{ 
  $match: { _id: 1 } 
},
{ 
  $lookup: {
      from: "users",
      let: { idVar: "$_id" , passesVar: "$passes" },
      pipeline: [
          { 
            $match: { 
                $expr: { 
                    $not: { $in: [ "$_id", { $concatArrays: [ "$$passesVar" , [ "$$idVar" ] ] } ] }
                } 
            } 
          },
      ],
      as: "usersAfterFilter"
}},
{ 
  $project: { 
      usersAfterFilter: 1, 
      _id: 0 
}}
])

输出:{ "usersAfterFilter" : [ { "_id" : 2 }, { "_id" : 9 } ] }

【讨论】:

    猜你喜欢
    • 2023-03-12
    • 2013-09-13
    • 2015-05-09
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    相关资源
    最近更新 更多