从 Node.js 向 MongoDB 集合插入不同类型的值

Posted

技术标签:

【中文标题】从 Node.js 向 MongoDB 集合插入不同类型的值【英文标题】:Insert values with different types to MongoDB collection from Node.js 【发布时间】:2018-03-17 05:38:05 【问题描述】:

我正在使用带有 Node.js 和 MongoDB 的 Sails Web 框架来创建我自己的网站。现在,我在尝试创建新用户并在发送发布请求时将值(来自不同类型:数字、数组、对象)插入我的“用户”集合时遇到了一些困难。 我想不通,为什么这里唯一有效的类型是“字符串”,例如,当我将类型更改为“数字”并通过 Postman 发送发布请求时,这是弹出的错误:

 "message": "Resolver error: \"age\" has wrong type",
    "name": "PARAMETER_WRONG_TYPE",

这是用户控制器:

create: function(req, res)
            var expectedInputs = [
            
                name: 'idsid',
                type: 'string',
                required: true
            
            ,
            
                name: 'age',
                type: 'Number',
                required: true
            
            ,
            
                name: 'last_name',
                type: 'string',
                required: true
            
                              ];

SanitizeService.allReqParams(req.allParams(), expectedInputs)
                .then(function(sanitizedInputs)
                    var user = ;
                    user.idsid = sanitizedInputs['idsid'];
                    user.age = sanitizedInputs['age'];
                    user.last_name = sanitizedInputs['last_name'];

                    return UserService.create(user);
                )
                .then(function(response)
                    res.ok(response);
                )
                .catch(function(err)
                    res.badRequest(err);
                );

        

这是在 UserService 中创建的函数:

create: function(user) 
        return new P(function(resolve, reject)
            sails.log.verbose('API Audit: UserService.create called');
            var rejection = new Error('UserService.create Error: ');
            user.Created = new Date();
            user.Modified = new Date();
            Users.native(function(err, collection)
                if(err)
                    rejection.message += 'problem connecting to collection';
                    return reject(rejection);
                
                collection.update('idsid': user.idsid, user, upsert: true, 
                    function(err, results)
                        if(err)
                            rejection.message += err;
                            return reject(rejection);
                         else 
                            return resolve(results);
                        
                    
                );
            );
      );
    

请让我知道是否还需要其他任何内容以了解该问题。 感谢您的帮助!

编辑: 如下所示,我尝试将类型更改为“integer”,这是我得到的错误:

"stack": "Error: Resolver error: wrong type \"integer\"\n    at Resolver.addParameter (C:\\workspace\\node_modules\\input-resolver\\index.js:81:13)\n    at C:\\workspace\\api\\services\\SanitizeService.js:57:15\n    at Array.forEach (native)\n    at C:\\workspace\\api\\services\\SanitizeService.js:5

我不确定这是否必要,但这是输入解析器

function ResolverError(msg, name) 
  this.message = msg;
  this.name = name;


ResolverError.prototype = new Error();

function Resolver() 
  this.parameters = [];
  this.asPromise = false;


Resolver.types = ['string', 'boolean', 'number', 'object', 'array'];

Resolver.checkType = function(param, type) 
  return type == 'array' ? Array.isArray(param) : typeof param === type;
;

Resolver.prototype.asPromise = function(asPromise)

    this.asPromise = (typeof asPromise == 'boolean') ? asPromise : true;
;

Resolver.prototype.getParameter = function(name, parent) 
  if (!this.parameters.length) 
    return null;
  

  parent = typeof parent == 'string' && '' != parent ? parent : null;
  for (var i = 0, len = this.parameters.length; i < len; i++) 
    if (name === this.parameters[i].name) 
      if (parent && parent != this.parameters[i].parent) continue;

      return this.parameters[i];
    
  

  return null;
;

Resolver.prototype.getAllParameters = function() 
  return this.parameters;
;

Resolver.prototype.addParameter = function(param) 
  var checkParameter = function(param) 
    if (typeof param != 'object') 
      return false;
    

    if (!param.name || typeof param.required != 'boolean') 
      return false;
    

    return true;
  ;

  if (!checkParameter(param)) 
    throw new ResolverError(
      'Resolver error: parameter not valid',
      'PARAMETER_NOT_VALID'
    );
  

  var paramFound = this.getParameter(param.name, param.parent);
  if (null !== paramFound) 
      throw new ResolverError(
          'Resolver error: trying to overwrite "' + param.name + '" parameter',
          'PARAMETER_OVERWRITE'
      );
  

  var p = 
    name: param.name,
    required: param.required,
    parent: null
  ;

  if (typeof param.type != 'undefined') 
    if (Resolver.types.indexOf(param.type) == -1) 
      throw new Error('Resolver error: wrong type "' + param.type + '"');
    

    p.type = param.type;
  

  if (typeof param.default != 'undefined') 
    if (p.required) 
      throw new Error(
        'Resolver error: trying to set default value to required parameter'
      );
    

    if (p.type && !Resolver.checkType(param.default, p.type)) 
      throw new Error(
        'Resolver error: default value doesn\'t match the param type'
      );
    

    p.default = param.default;
  

  if (typeof param.values != 'undefined') 
    if (!Array.isArray(param.values)) 
      throw new Error('Resolver error: available values is not an array');
    

    if (!param.values.length) 
      throw new Error('Resolver error: available values array is empty');
    

    p.values = param.values;
  

  if (typeof param.parent == 'string') 
    if ('' == param.parent) 
        throw new Error(
          'Resolver error: parent property for "' + param.name +
          '" is an empty string'
        );
    

    var parentParam = this.getParameter(param.parent);
    if (null !== parentParam) 
      if (parentParam.type && parentParam.type != 'object') 
        throw new Error(
          'Resolver error: parent for parameter "' + param.name + '"' +
          ' is defined, but has type of "' + parentParam.type + '" instead of' +
          ' "object"'
        );
      

      parentParam.type = 'object';
      parentParam.required = true;
     else 
      this.parameters.unshift(
        name: param.parent,
        required: true,
        type: 'object',
        parent: null
      );
    

    p.parent = param.parent;
  

  this.parameters.push(p);

  return this;
;

Resolver.prototype._resolve = function(data, callback) 
  var getKeys = function(obj) 
    if (typeof obj != 'object') 
      return [];
    

    var keys = [];
    for (var k in obj) 
      keys.push(k);
    

    return keys;
  ;

  if (!this.parameters.length) 
    return callback(
      new ResolverError(
        'Resolver error: no parameters specified',
        'NO_RESOLVER_PARAMETERS'
      )
    );
  

  if (!getKeys(data).length) 
    return callback(
      new ResolverError(
        'Resolver error: empty data provided',
        'EMPTY_DATA'
      )
    );
  

  var resolved = ;
  for (var i = 0; i < this.parameters.length; i++) 
    var param = this.parameters[i];

    var parameterData = param.parent ? data[param.parent][param.name] :
      data[param.name]
    ;

    if (param.required) 
      if (typeof parameterData == 'undefined') 
        return callback(
          new ResolverError(
            'Resolver error: "' + param.name + '" required parameter not found',
            'NO_REQUIRED_PARAMETER'
          )
        );
      
     else 
      if (
        typeof parameterData == 'undefined' &&
        typeof param.default == 'undefined'
      ) 
        continue;
      

      parameterData = typeof parameterData == 'undefined' ?
      param.default : parameterData;
    

    if (
      typeof param.type == 'string' &&
      !Resolver.checkType(parameterData, param.type)
    ) 
      return callback(
        new ResolverError(
          'Resolver error: "' + param.name + '" has wrong type',
          'PARAMETER_WRONG_TYPE'
        )
      );
    

    if (param.values && param.values.indexOf(parameterData) == -1) 
      return callback(
        new ResolverError(
          'Resolver error: "' + param.name + '" has wrong value',
          'PARAMETER_WRONG_VALUE'
        )
      );
    

    if (param.parent) 
      resolved[param.parent][param.name] = parameterData;
     else 
      resolved[param.name] = parameterData;
    
  

  return callback(null, resolved);
;

Resolver.prototype.resolve = function(data, callback) 
    this._resolve(data, callback);
;

Resolver.prototype.resolvePromise = function(inputData) 
    var _this = this;
    return new Promise(function(fulfill, reject) 
        _this._resolve(inputData, function(err, data) 
            if (err) return reject(err);
            return fulfill(data);
        );
    );
;

module.exports = Resolver;

【问题讨论】:

【参考方案1】:

您必须使用sails mongo 与mongo db 交互,因为您提到这是一个sails 项目。

Sails 模型不提供 Number 类型,而是提供整数和浮点数。

sails 模型支持的数据类型有:

字符串 文字 整数 浮动 日期 日期时间 布尔值 二进制 数组 json 中文本 长文本 objectid

请检查: http://sailsjs.com/documentation/concepts/models-and-orm/attributes 您可能希望将类型从 Number 更改为 int。

【讨论】:

感谢您的评论,我的原帖是根据这个建议编辑的。 我想知道您是否参考了一些与sails mongo 相关的文档或教程,因为您将使用sails 添加用户到mongo 的场景的代码复杂化。请参考此链接并告诉我它是否与您的要求不同。我建议您阅读此文档:sailsjs.com/documentation/concepts/models-and-orm :)

以上是关于从 Node.js 向 MongoDB 集合插入不同类型的值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 node.js 中重用 mongodb 连接

如何从 Socket.IO 向数组 (MongoDB) 添加数据? (node.js)

MongoDB 使用 Node.js 获取集合中的文档数(计数)

MongoDB 集合连字符名称

Node.JS、Express 和 MongoDB :: 多个集合

Node.js REST API 从 MongoDB 获取数据