首页 > 解决方案 > mongoose:持续保存数据

问题描述

我正在尝试将更新后的 websocket 数据保存到 mongodb 中,并能够使用 GQL 查询数据!我将不得不返工我所拥有的,但我只是对如何去做这件事有点困惑?

无论如何,任何帮助将不胜感激<3

const mongoose = require('mongoose');

mongoose.connect("URI", {
  useNewUrlParser: true,
  useFindAndModify: false,
  useCreateIndex: true,
  useUnifiedTopology: true,
});


const { ApolloServer, PubSub, gql } = require('apollo-server');

const pubsub = new PubSub();

// saves in db as plural eg: btcusdklines ???
const BTCUSDkline = mongoose.model("BTCUSDkline",{
    time: Number,
    open: Number,
    high: Number,
    low: Number,
    close: Number,
});

const typeDefs = gql`
  type Query {
      getBTCUSDkline: [BTCUSDkline]
  }
  type BTCUSDkline {
      id: ID!
      time: Int
      open: Int
      high: Int
      low: Int
      close: Int
  }
`;

const resolvers = {
  Query: {
      getBTCUSDkline: ()=> BTCUSDkline.find(),
  },
}

const server = new ApolloServer({ 
  typeDefs, 
  resolvers,
});

server.listen().then(({ url }) => {
  console.log(` server live @ ${url}`);
});

const ws = new WebsocketClient({key: API_KEY, secret: PRIVATE_KEY}, logger);

ws.subscribe(["klineV2.1.BTCUSD"]);

ws.on('open', function() {
    console.log('connection open');
});

ws.on('update', function(message) {
    const btcusdOpen = message.data[0].open;
    const btcusdClose = message.data[0].close;
    const btcusdHigh = message.data[0].high;
    const btcusdLow = message.data[0].low;
    const btcusdTime = message.data[0].timestamp;

    console.log(message);

    // define Schema
    var BTCUSDklineSchema = mongoose.Schema({
      time: Number,
      open: Number,
      high: Number,
      low: Number,
      close: Number,
    });
    // compile schema to model
    var Data = mongoose.model('Data', BTCUSDklineSchema, 'BTCUSDkline');

    // a document instance
    var data1 = new Data({ time:btcusdTime, open:btcusdOpen, high:btcusdHigh, low:btcusdLow, close: btcusdClose });

    // save model to database
    data1.save(function (data) {
      console.log("just saved to BTCUSDkline collection!");
    });

});

ws.on('response', function(response) {
    console.log('response', response);
});

ws.on('close', function() {
    console.log('connection closed');
}); 
ws.on('error', function(err) {
    console.error('ERR', err);
}); 

第一次有效,但第二次抛出以下错误:

throw new _mongoose.Error.OverwriteModelError(name);
      ^

OverwriteModelError: Cannot overwrite `Data` model once compiled.

标签: node.jsmongoosewebsocketapolloapollo-server

解决方案


您应该将模式放在函数之外,也许是在调用 mongoose 本身之后,所以一旦设置和编译它们,它们将在全局范围内从 mongoose 可用。

每次有人通过ws发送东西时,该函数都会尝试定义Data Schema,之前mongoose已经定义和编译过了。

而不是在函数中定义 Schame,如下所示:

ws.on('update', function(message) {
    // ... message definition

    // define Schema
    var BTCUSDklineSchema = mongoose.Schema({
      time: Number,
      open: Number,
      high: Number,
      low: Number,
      close: Number,
    });
    // compile schema to model
    var Data = mongoose.model('Data', BTCUSDklineSchema, 'BTCUSDkline');

    // a document instance
    var data1 = new Data({ time:btcusdTime, open:btcusdOpen, high:btcusdHigh, low:btcusdLow, close: btcusdClose });

    // save model to database
    data1.save(function (data) {
      console.log("just saved to BTCUSDkline collection!");
    });
});

您应该在任何函数之外设置 Schema,如下所示:

// define Schema
const BTCUSDklineSchema = mongoose.Schema({
  time: Number,
  open: Number,
  high: Number,
  low: Number,
  close: Number,
});

// compile schema to model
const Data = mongoose.model('Data', BTCUSDklineSchema, 'BTCUSDkline');

ws.on('update', function(message) {
    // ... message definition

    // a document instance
    var data1 = new Data({ time:btcusdTime, open:btcusdOpen, high:btcusdHigh, low:btcusdLow, close: btcusdClose });

    // save model to database
    data1.save(function (data) {
      console.log("just saved to BTCUSDkline collection!");
    });
});

推荐阅读