You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB插入报错:TypeError: Cannot read properties of null (reading 'readPreference')

MongoDB插入数据报错:TypeError: Cannot read properties of null (reading 'readPreference')

我在MongoDB表插入数据时遇到问题,搞不懂报错里的null是什么意思。出现的错误是:TypeError: Cannot read properties of null (reading 'readPreference')。

我想弄明白几个问题:

  • 是否需要用mongosh手动创建特定的库或集合?
  • 相关函数能不能自动创建文档和集合?

相关代码如下:

addUser函数

const addUser = async (req, res) => {
    try {
      let user = new User(
        req.body.names,
        req.body.adress,
        req.body.phone
      );
      let result = await client
        .db()
        .collection("users")
        .insertOne(user);
  
      res.status(200).json(result);
    } catch (error) {
      console.log(error);
      res.status(501).json(error);
    }
  };

User类

class User {
    constructor(names, adress, phone) {
        this.names = names;
        this.adress =  adress;
        this.phone = phone;
    }
}

db函数

function db() {
  var db = new Db(client, "connected");
  return db;
}

我已经尝试修改过部分函数参数,也查阅了collection和insertOne的文档,但问题还是没解决。


问题分析与解决方案

报错核心原因

这个错误的本质是client对象未正确初始化或为null。当调用client.db()时,因为client本身是null,无法读取它的db方法,后续链式调用collection和insertOne时就触发了Cannot read properties of null的错误。另外你的db函数写法完全错误:MongoDB Node.js驱动中,Db类不能直接通过new Db(client, "connected")实例化,正确方式是通过已连接的client调用db("数据库名")获取数据库对象。

关于库和集合的创建

MongoDB采用懒加载机制:

  • 不需要手动创建数据库,第一次向某个数据库写入数据时,数据库会自动创建。
  • 集合也不需要手动创建,第一次向某个集合插入文档时,集合会自动创建。
    所以你完全不需要用mongosh提前创建库或集合。

修复步骤

  1. 确保MongoDB客户端正确连接
    必须先完成client的初始化和连接,示例代码:

    const { MongoClient } = require('mongodb');
    const uri = 'mongodb://localhost:27017'; // 替换为你的MongoDB连接字符串
    let client;
    
    async function connectDB() {
      if (!client) {
        client = new MongoClient(uri);
        await client.connect();
        console.log('MongoDB连接成功');
      }
      return client;
    }
    

    在addUser函数中,必须先调用connectDB()获取已连接的client,不能直接使用未初始化的client。

  2. 修正数据库获取逻辑
    删除你当前的db函数,直接通过已连接的client指定数据库名:

    // 在addUser中修改为:
    const connectedClient = await connectDB();
    let result = await connectedClient
      .db("connected") // 这里明确指定数据库名
      .collection("users")
      .insertOne(user);
    
  3. 简化User类的使用(可选)
    没必要专门定义User类,直接用对象字面量即可,避免构造函数可能带来的冗余:

    let user = {
      names: req.body.names,
      adress: req.body.adress,
      phone: req.body.phone
    };
    

完整修正后的addUser示例

const { MongoClient } = require('mongodb');
const uri = 'mongodb://localhost:27017';
let client;

async function connectDB() {
  if (!client) {
    client = new MongoClient(uri);
    await client.connect();
  }
  return client;
}

class User {
    constructor(names, adress, phone) {
        this.names = names;
        this.adress =  adress;
        this.phone = phone;
    }
}

const addUser = async (req, res) => {
    try {
      let user = new User(
        req.body.names,
        req.body.adress,
        req.body.phone
      );
      const connectedClient = await connectDB();
      let result = await connectedClient
        .db("connected")
        .collection("users")
        .insertOne(user);
  
      res.status(200).json(result);
    } catch (error) {
      console.log(error);
      res.status(501).json({ error: error.message });
    }
  };

内容的提问来源于stack exchange,提问作者user17065577

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 04:45:42