Nodejs mongoose这样设置schema为什么老出错

Nodejs mongoose这样设置schema为什么老出错

 db.once(‘open’,function(){
var m39 = mongoose.Schema({
id:Number,//采集的地址
date:{type:Date,default:Date.now},
question:{
content:String,
author:String
},
answer:{
id:{
content:String,
author:String
}
},
url:String
})
var c_39_url = mongoose.model(‘c_39_url’,m39)
}

求改进


3 回复

根据你提供的代码片段,有几个潜在的问题需要解决。以下是对代码的分析及改进建议:

  1. mongoose.Schema 的定义位置

    • 在 Mongoose 中,你应该先定义 Schema,然后再基于该 Schema 创建 Model。你的代码中将 Schema 定义放在了 db.once('open', function(){...}) 回调函数内部,这会导致每次数据库打开时都会重新定义 Schema,可能会导致不必要的重复定义或冲突。
  2. Schema 字段定义问题

    • answer.id 字段定义有问题,id 应该是一个字符串或者数字,而不是一个对象。如果 id 是唯一标识符,建议将其作为顶层字段,而不是嵌套在 answer 对象中。
  3. mongoose.model 的使用

    • 确保在创建 Model 之前,对应的 Collection 已经存在或者已经通过 Schema 定义自动创建。如果你在创建 Model 之前没有正确地连接到数据库,那么 Model 可能无法正常工作。

改进后的代码

const mongoose = require('mongoose');

// 定义 Schema
var m39 = new mongoose.Schema({
    id: Number, // 采集的地址
    date: { type: Date, default: Date.now },
    question: {
        content: String,
        author: String
    },
    answer: {
        content: String, // 假设这里需要的是答案的内容
        author: String
    },
    url: String,
    answerId: String // 如果你需要一个独立的 ID 来标识答案
});

// 创建 Model
var C39Url = mongoose.model('c_39_url', m39);

// 连接到数据库
mongoose.connect('mongodb://localhost/your_database_name', {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then(() => {
    console.log("Connected to MongoDB");
}).catch((err) => {
    console.error("Connection error", err);
});

// 现在你可以使用 C39Url Model 进行 CRUD 操作

解释

  • Schema 定义:将 Schema 定义移到 mongoose.connect 之后,确保它只被定义一次,并且在整个应用生命周期中保持一致。
  • Model 名称mongoose.model 的第一个参数是 Model 的名称,Mongoose 会自动将其转换为集合名(例如 c_39_url 将被转换为 c_39_urls 集合)。
  • 错误处理:添加了数据库连接的错误处理逻辑,以便于调试。

通过上述改进,你的 Schema 和 Model 应该能够正常工作,避免之前出现的错误。


完整代码

    /**
 * 采集39问答网
 */

var n = require(‘needle’) var $ = require(‘jquery’).create() var iconv = require(‘iconv’).Iconv; var lite = require(‘iconv-lite’) var mongoose = require(‘mongoose’); var async = require(‘async’) mongoose.connect(‘mongodb://localhost/cj’); var db = mongoose.connection; db.on(‘error’, console.error.bind(console, ‘connection error:’)); var question = [] var answer = [] //一。采集第一集分类的链接地址 var one = function(error,response,body){ var content = new iconv(‘gbk’,‘UTF-8//TRANSLIT//IGNORE’).convert(new Buffer(body,‘binary’)).toString() //标题 question[‘title’] = $(content).find(‘title’).text() $.each($(content).find(’.tboxs’),function(i,v){ $(v).find(’.anniu’).nextAll().remove() $(v).find(’.tousu’).remove() $(v).find(’.anniu’).remove() var cc = $(v).find(’.tbrig’).html()//内容 var a = $(v).find(’.username’).text() if(i == 0) { question[‘question’] = {content:cc,author:a} } else { answer.push({content:cc,author:a}) } }) console.log(question) db.once(‘open’,function(){ var m39 = mongoose.Schema({ id:Number,//采集的地址 date:{type:Date,default:Date.now}, question:{ content:String, author:String }, answer:{ id:{ content:String, author:String } }, url:String }) var c_39_url = mongoose.model(‘c_39_url’,m39) } }

n.get(‘http://ask.39.net/question/24749283.html’,{decode_response:false,encoding:'binary’},one)

从你提供的代码片段来看,问题在于Schema定义以及模型注册的部分。这里有几个需要注意的地方:

  1. Schema定义:你的Schema定义是正确的,但建议给每个字段添加required: true以确保数据完整性。
  2. 模型注册时机:你试图在数据库连接成功后定义Schema并注册模型,但是这段代码应该放在外部以便多次调用时不会重复定义。

以下是一个改进后的版本:

const mongoose = require('mongoose');

// 定义Schema
const m39Schema = new mongoose.Schema({
    id: { type: Number, required: true }, // 采集的地址
    date: { type: Date, default: Date.now },
    question: {
        content: { type: String, required: true },
        author: { type: String, required: true }
    },
    answer: {
        content: { type: String, required: true },
        author: { type: String, required: true }
    },
    url: { type: String, required: true }
});

// 注册模型
const C39Url = mongoose.model('c_39_url', m39Schema);

// 连接数据库后使用模型
db.once('open', function () {
    // 你可以在这里使用C39Url模型进行操作
});

解释:

  • Schema定义:在文件顶部定义Schema,而不是在数据库连接成功后再定义。这样可以避免重复定义。
  • 模型注册:将模型注册放在外部,确保它只被定义一次。
  • 验证:为关键字段添加required: true来保证数据的有效性。

这样修改后,你应该不会再遇到定义错误,并且可以在数据库连接成功后直接使用C39Url模型进行CRUD操作。

回到顶部