【问题标题】:Mongoose - Searching Schema via findOne() unsuccessfullyMongoose - 通过 findOne() 搜索架构失败
【发布时间】:2015-08-28 21:24:56
【问题描述】:

在通过 MongoDB 为 express-session 设置 sessionStore 时,我在使用 findOne() 函数验证用户信息是否有效且最新时遇到了一些麻烦。

var session = require('express-session');
var mongoStore = require('connect-mongo')(session);
var mongoose = require('mongoose');

var Schema = mongoose.Schema;
var Session = mongoose.model('session', new Schema({
    sid : String,
    username : String,
    email : String
}));

...

不过,诀窍在于 express-sessionconnect-mongo 负责管理对数据库的写入。

app.use(session({
    secret: 'secretsquirrel',
    resave: true,
    saveUninitialized: true,
    store: new mongoStore({
        mongoseConnection: mongoose.connection,
        host: '127.0.0.1',
        port: '27017',
        db: 'testdb',
        collection: 'collectionName'
    })
}));

现在,这似乎可以正常工作,因为文档已输入到我指定的集合中。从集合中返回数据会产生以下结果:

{  
   "_id":"sdBYsdflAsdfyWPPneV-hrC2xsXP",
   "session":"
   {
       \"cookie\":
       {
        \"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"
       },
       \"email\":\"testuser@email.com\",
       \"username\":\"testuser\",
       \"sid\":\"f59106e845e11df8c3413b5f1f80ee01e876526bc3c0d05\",
   }",
   "expires":   ISODate(DateHere)
}

问题似乎出在数据库中,或者通过 Mongoose,我尝试如何查询 SID 似乎并不重要,我使用以下任何方法都不返回任何结果:

通过 Mongo:

db.collectionName.findOne({ session.sid: "sid" })
db.collectionName.findOne({ "session.sid": "sid" })
db.collectionName.findOne({ "session": { "\"sid\"": "sid" } })

通过猫鼬 (NodeJS)

Session.findOne({ sid: req.session.sid }, function(err, data) {...});
Session.findOne({ "sid": req.session.sid }, function(err, data) {...});
Session.findOne({ "\"sid"\"": "\"" + req.session.sid + "\"" }, function(err, data) {...});

问题是,在这两种情况下我都无法返回我已验证在集合中的任何数据,这是怎么回事?我是否需要像我一直在尝试做的那样考虑文档中返回的转义引号,还是仅仅通过 mongo shell 输出?

我是否缺少正确搜索此数据的任何步骤?非常感谢您有一双新鲜的眼睛!

解决方案:

vinagreti 指出保存到我​​的集合中的数据不是对象,而是纯文本。

通过引用connect-mongo's documentationstringify 有一个额外的选项。此设置字符串化并将会话保存的数据序列化到数据库中。考虑到 express-session 已经生成了一个 JSON 对象,使用 stringify() 使其无法在集合中搜索。

只需将stringify: false 添加到我的 mongoStore 设置中,如下所示:

store: new mongoStore({
        mongoseConnection: mongoose.connection,
        host: '127.0.0.1',
        port: '27017',
        db: 'testdb',
        collection: 'collectionName',
        stringify: false
    })

然后瞧!保存到集合中的所有内容现在都是对象并且可以搜索!感谢 vinagreti 帮助指出问题!请为他的回答点赞!

【问题讨论】:

    标签: node.js mongodb mongoose express-session connect-mongo


    【解决方案1】:

    您正在将会话对象保存为纯文本。因此,您无法作为对象进行搜索。

    确保“父亲”集合的架构具有类型为“{}”(对象)的会话字段,例如:Father = {session: { type: {} }}

    如果还是不行,可以试试下面的方法:

    您可以更改保存会话对象的方式,将其保存为对象,而不是纯文本。

    或者,您可以使用正则表达式搜索会话,尝试在会话字段中查找 sid,例如:

    db.user.findOne({session: /.*f59106e845e11df8c3413b5f1f80ee01e876526bc3c0d05.*/});
    

    【讨论】:

    • 如何将会话对象保存为对象? Mongoose 模式是否像这样不关心保存,还是对象中的每个项目都是明文?
    • 猫鼬会为你处理这件事。检查您是否将真实对象传递给猫鼬。也许你正在传递一个字符串。尝试使用 JSON.parse(jsonString);在保存之前将会话字符串转换为对象。
    • 架构的项目是字符串,但诀窍是express-sessionconnect-mongo 一起负责将架构写入数据库。
    • 您能否为具有会话字段的对象显示您的架构?在我的示例中,我使用了“用户”。我认为您的架构应该将 {} 作为类型或对会话架构的引用,例如:{ type : Schema.Types.ObjectId, ref: 'Session' }
    • 看来我发现了问题!事实证明,connect-mongo 自动对数据进行字符串化和序列化,使其返回如上所示。将 stringify: false 添加到我的 mongoStore 设置时,它将数据保持原样 - 一个对象。
    猜你喜欢
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2021-05-17
    • 2018-03-04
    • 2015-12-06
    • 2023-02-10
    • 2022-12-03
    相关资源
    最近更新 更多