我正在尝试保存和更新findOneAndUpdate()
({upsert: true}
-如果不存在则创建对象)Web Api的结果,该Web Api包含多个数据数组以填充股票图表。每次输入符号并单击“获取报价”按钮,它都应从Web api获取数据,然后在数据库的“子模式”下保存/更新它。我该如何使用nodejs和mongoose?这是我尝试过的代码。...
文件夹-模型-Stock.js
const mongoose = require('mongoose')
mongoose.Promise = global.Promise
mongoose.connect('mongodb://localhost:27017/myapp', { useNewUrlParser: true })
const slug = require('slug')
const childSchemaData = new mongoose.Schema({
date: mongoose.Decimal128,
open: mongoose.Decimal128,
high: mongoose.Decimal128,
low: mongoose.Decimal128,
close: mongoose.Decimal128,
volume: mongoose.Decimal128
})
const parentSchemaSymbol = new mongoose.Schema({
symbol: {
type: String,
trim: true,
minlength: 2,
maxlength: 4,
required: 'Plese enter a valid symbol, min 2 characters and max 4'
},
// Array of subdocuments
data: [childSchemaData],
slug: String
});
//we have to PRE-save slug before save the parentSchemaSymbol into DB
parentSchemaSymbol.pre('save', function (next) {
if (!this.isModified('symbol')) {
next()//skip it
return//stop this function from running
}
this.slug = slug(this.symbol)
next()
//TODO make more resiliant soslug are unique
})
module.exports = mongoose.model('Stock', parentSchemaSymbol)
控制器-webApiController.js
const mongoose = require('mongoose')
const axios = require('axios')
require('../models/Stock')
const parentSchemaSymbol = mongoose.model('Stock')
mongoose.Promise = global.Promise // Tell Mongoose to use ES6 promises
// Connect to our Database and handle any bad connections
mongoose.connect('mongodb://localhost:27017/myapp', { useNewUrlParser: true })
mongoose.connection.on('error', (err) => {
console.error(` → ${err.message}`)
})
exports.webApi = (req, res) => {
let curValue = req.params.symbol
axios.get(`https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=${curValue}&outputsize=compact&apikey=TUVR`)
.then(response => {
return highLow = Object.keys(response.data['Time Series (Daily)']).map(date => {
return {
date: Date.parse(date),
open: Math.round(parseFloat(response.data['Time Series (Daily)'][date]['1. open']) * 100) / 100,
high: Math.round(parseFloat(response.data['Time Series (Daily)'][date]['2. high']) * 100) / 100,
low: Math.round(parseFloat(response.data['Time Series (Daily)'][date]['3. low']) * 100) / 100,
close: Math.round(parseFloat(response.data['Time Series (Daily)'][date]['4. close']) * 100) / 100,
volume: parseInt(response.data['Time Series (Daily)'][date]['5. volume'])
}
})
})
.then(_ => {
let curValueSchema = new parentSchemaSymbol()
curValueSchema.symbol = curValue
highLow.map(item => {
curValueSchema.data.push(item)
})
const query = { symbol: `${curValue.toUpperCase()}` }
const update = { $addToSet: { data: [curValueSchema.data] } }
const options = { upsert: true, new: true }
curValueSchema.findOneAndUpdate(query, update, options).then(doc => {
console.log('Saved the symbol', doc)
return res.send(highLow)
}).catch(e => {
console.log(e)
})
})
.catch(error => {
console.log(error)
})
}
这是我要修复的代码。其余的工作正常:
let curValueSchema = new parentSchemaSymbol()
curValueSchema.symbol = curValue
highLow.map(item => {
curValueSchema.data.push(item)
})
const query = { symbol: `${curValue.toUpperCase()}` }
const update = curValueSchema
const options = { upsert: true, new: true }
curValueSchema.findOneAndUpdate(query, update, options).then(doc => {
console.log('Saved the symbol', doc)
return res.send(highLow)
}).catch(e => {
console.log(e)
})
这是我遇到的错误
TypeError: curValueSchema.findOneAndUpdate is not a function
at axios.get.then.then._ (/mnt/c/Users/john/Desktop/node/controllers/webApiController.js:55:22)
at process._tickCallback (internal/process/next_tick.js:178:7)
这是数据= highLow
解决方案
因为默认情况下,Mongoose在每次向其传递Javascript对象以更新文档字段时都会创建一个新的MongoDB ObjectId(此隐藏的_id字段)。
要遍历您,可以通过确保您的猫鼬模式如下来告诉Mongoose不要创建新的ObjectId:
文件夹-模型-Stock.js
const mongoose = require('mongoose')
mongoose.Promise = global.Promise
mongoose.connect('mongodb://localhost:27017/myapp', { useNewUrlParser: true })
const slug = require('slug')
const childSchemaData = new mongoose.Schema({
"_id": false,
date: mongoose.Decimal128,
open: mongoose.Decimal128,
high: mongoose.Decimal128,
low: mongoose.Decimal128,
close: mongoose.Decimal128,
volume: mongoose.Decimal128
})
const parentSchemaSymbol = new mongoose.Schema({
"_id": false,
symbol: {
type: String,
trim: true,
minlength: 2,
maxlength: 4,
required: 'Plese enter a valid symbol, min 2 characters and max 4'
},
// Array of subdocuments
data: [childSchemaData],
slug: String
});
//we have to PRE-save slug before save the parentSchemaSymbol into DB
parentSchemaSymbol.pre('save', function (next) {
if (!this.isModified('symbol')) {
next()//skip it
return//stop this function from running
}
this.slug = slug(this.symbol)
next()
//TODO make more resiliant soslug are unique
})
module.exports = mongoose.model('Stock', parentSchemaSymbol)
控制器-webApiController.js
let curValueSchema = new parentSchemaSymbol()
curValueSchema.symbol = curValue
highLow.map(item => {
curValueSchema.data.push(item)
})
const query = { symbol: `${curValue.toUpperCase()}` }
const update = curValueSchema
const options = { upsert: true, new: true }
parentSchemaSymbol.findOneAndUpdate(query, update, options).then(doc => {
console.log('Saved the symbol', doc)
return res.send(highLow)
}).catch(e => {
console.log(e)
})
答案 0 :(得分:1)
代替:
curValueSchema.findOneAndUpdate
要做:
parentSchemaSymbol.findOneAndUpdate
答案 1 :(得分:1)
这是模型的方法,而不是实例。 用方案名称替换实例名称。
答案 2 :(得分:1)
let curValueSchema = new parentSchemaSymbol()
curValueSchema.symbol = curValue
highLow.map(item = > {
curValueSchema.data.push(item)
})
const query = {
symbol: `$ {
curValue.toUpperCase()
}`
}
const update = curValueSchema
const options = {
upsert: true,
new: true
}
parentSchemaSymbol.findOneAndUpdate(query, update, options).then(doc = > {
console.log('Saved the symbol', doc)
return res.send(highLow)
}).
catch (e = > {
console.log(e)
})