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)
}
求改进
根据你提供的代码片段,有几个潜在的问题需要解决。以下是对代码的分析及改进建议:
-
mongoose.Schema
的定义位置:- 在 Mongoose 中,你应该先定义 Schema,然后再基于该 Schema 创建 Model。你的代码中将 Schema 定义放在了
db.once('open', function(){...})
回调函数内部,这会导致每次数据库打开时都会重新定义 Schema,可能会导致不必要的重复定义或冲突。
- 在 Mongoose 中,你应该先定义 Schema,然后再基于该 Schema 创建 Model。你的代码中将 Schema 定义放在了
-
Schema 字段定义问题:
answer.id
字段定义有问题,id
应该是一个字符串或者数字,而不是一个对象。如果id
是唯一标识符,建议将其作为顶层字段,而不是嵌套在answer
对象中。
-
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定义以及模型注册的部分。这里有几个需要注意的地方:
- Schema定义:你的Schema定义是正确的,但建议给每个字段添加
required: true
以确保数据完整性。 - 模型注册时机:你试图在数据库连接成功后定义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操作。