Mongoose 找到一个并推送到文档数组

2023-12-12

我是 MongoDB 和 Mongoose 的新手,我正在尝试使用它来保存股票报价以进行日间交易分析。所以我想象了这个架构:

symbolSchema = Schema({
    name:String,
    code:String
});

quoteSchema = Schema({
    date:{type:Date, default: now},
    open:Number, 
    high:Number,
    low:Number,
    close:Number,
    volume:Number
});

intradayQuotesSchema = Schema({
    id_symbol:{type:Schema.Types.ObjectId, ref:"symbol"},
    day:Date,
    quotes:[quotesSchema]
});

从我的链接我每分钟都会收到这样的信息:

日期 |符号|打开|高|低|关闭 |体积

2015-03-09 13:23:00|AAPL|127,14|127,17|127,12|127,15|19734

我必须:

  1. 查找符号 (AAPL) 的 ObjectId。
  2. 检测该交易品种的intradayQuote文档是否已存在(交易品种和日期组合)
  3. 检测该交易品种的分钟 OHLCV 数据是否存在于报价数组中(因为它可能会重复)
  4. 更新或创建文档并更新或创建数组内的引号

我可以在不验证引号是否已存在的情况下完成此任务,但此方法可以在引号数组内创建重复的条目:

symbol.find({"code":mySymbol}, function(err, stock) {
    intradayQuote.findOneAndUpdate({
        { id_symbol:stock[0]._id, day: myDay },
        { $push: { quotes: myQuotes } },
        { upsert: true },
        myCallback
    });
});

我已经尝试过:

  • $addToSet而不是 $push,但不幸的是,这似乎不适用于文档数组
  • { id_symbol:stock[0]._id, day: myDay, 'quotes["date"]': myDate }的条件查找并更新;但不幸的是,如果 mongo 找不到它,它会立即创建一个新文档,而不是附加到引号数组中。

有没有一种方法可以在不使用更多查询的情况下使其正常工作(我已经使用了 2 个查询)?我应该重新考虑我的架构来促进这项工作吗?任何帮助将不胜感激。谢谢!


基本上放了一个$addToSet运算符无法为您工作,因为您的数据不是真实的"set"根据定义,它是“完全不同”对象的集合。

这里的另一个逻辑意义是,您将在数据到达时对其进行处理,无论是作为单个对象还是提要。我假设它是某种形式的许多项目的提要,并且您可以使用某种流处理器来获得每个收到的文档的结构:

{
    "date": new Date("2015-03-09 13:23:00.000Z"),
    "symbol": "AAPL",
    "open": 127.14
    "high": 127.17,
    "low": 127.12 
    "close": 127.15,
    "volume": 19734
}

转换为标准十进制格式以及 UTC 日期,因为当然,一旦从数据存储中检索数据,任何区域设置实际上都应该是应用程序的域。

我还至少会通过删除对其他集合的引用并将数据放在那里来稍微展平您的“intraDayQuoteSchema”。您仍然需要在插入时进行查找,但是读取时额外填充的开销似乎比存储开销更高:

intradayQuotesSchema = Schema({
    symbol:{
        name: String,
        code: String
    },
    day:Date,
    quotes:[quotesSchema]
});

这取决于您的使用模式,但这种方式可能会更有效。

剩下的实际上取决于什么是可以接受的

stream.on(function(data) {

    var symbol = data.symbol,
        myDay = new Date( 
            data.date.valueOf() - 
                ( data.date.valueOf() % 1000 * 60 * 60 * 24 ));
    delete data.symbol;

    symbol.findOne({ "code": symbol },function(err,stock) {

        intraDayQuote.findOneAndUpdate(
            { "symbol.code": symbol , "day": myDay },
            { "$setOnInsert": { 
               "symbol.name": stock.name
               "quotes": [data] 
            }},
            { "upsert": true }
            function(err,doc) {
                intraDayQuote.findOneAndUpdate(
                    {
                        "symbol.code": symbol,
                        "day": myDay,
                        "quotes.date": data.date
                    },
                    { "$set": { "quotes.$": data } },
                    function(err,doc) {
                        intraDayQuote.findOneAndUpdate(
                            {
                                "symbol.code": symbol,
                                "day": myDay,
                                "quotes.date": { "$ne": data.date }
                            },
                            { "$push": { "quotes": data } },
                            function(err,doc) {

                            }
                       );    
                    }
                );
            }
        );    
    });
});

如果您实际上不需要响应中修改的文档,那么通过在此处实现批量操作 API 并在单个数据库请求中发送此包中的所有更新,您将获得一些好处:

stream.on("data",function(data) {

    var symbol = data.symbol,
        myDay = new Date( 
            data.date.valueOf() - 
                ( data.date.valueOf() % 1000 * 60 * 60 * 24 ));
    delete data.symbol;

     symbol.findOne({ "code": symbol },function(err,stock) {
         var bulk = intraDayQuote.collection.initializeOrderedBulkOp();
         bulk.find({ "symbol.code": symbol , "day": myDay })
             .upsert().updateOne({
                 "$setOnInsert": { 
                     "symbol.name": stock.name
                     "quotes": [data] 
                 }
             });

         bulk.find({
             "symbol.code": symbol,
             "day": myDay,
             "quotes.date": data.date
         }).updateOne({
             "$set": { "quotes.$": data }
         });

         bulk.find({
             "symbol.code": symbol,
             "day": myDay,
             "quotes.date": { "$ne": data.date }
         }).updateOne({
             "$push": { "quotes": data }
         });

         bulk.execute(function(err,result) {
             // maybe do something with the response
         });            
     });
});

关键是只有其中一个语句会实际修改数据,并且由于所有这些都是在同一个请求中发送的,因此应用程序和服务器之间的来回次数较少。

另一种情况是,在这种情况下,在另一个集合中引用实际数据可能会更简单。然后,这就变成了处理更新插入的简单问题:

intradayQuotesSchema = Schema({
    symbol:{
        name: String,
        code: String
    },
    day:Date,
    quotes:[{ type: Schema.Types.ObjectId, ref: "quote" }]
});


// and in the steam processor

stream.on("data",function(data) {

    var symbol = data.symbol,
        myDay = new Date( 
            data.date.valueOf() - 
                ( data.date.valueOf() % 1000 * 60 * 60 * 24 ));
    delete data.symbol;

    symbol.findOne({ "code": symbol },function(err,stock) {
         quote.update(
            { "date": data.date },
            { "$setOnInsert": data },
            { "upsert": true },
            function(err,num,raw) {
                if ( !raw.updatedExisting ) {
                    intraDayQuote.update(
                        { "symbol.code": symbol , "day": myDay },
                        { 
                            "$setOnInsert": {
                                "symbol.name": stock.name
                            },
                            "$addToSet": { "quotes": data }
                        },
                        { "upsert": true },
                        function(err,num,raw) {

                        }
                    );
                }
            }
        );
    });
});

这实际上取决于将报价数据嵌套在“日”文档中对您来说有多重要。主要区别是,如果您想根据其中一些“引用”字段的数据查询这些文档,或者以其他方式承受使用的开销.populate()从其他集合中提取“引用”。

当然,如果引用并且报价数据对您的查询过滤很重要,那么您始终可以只查询该集合以获取_id匹配并使用的值$in对“day”文档的查询仅匹配包含那些匹配的“quote”文档的日期。

这是一个重大决定,最重要的是根据应用程序使用数据的方式采取哪条路径。希望这可以指导您了解实现您想要实现的目标背后的一般概念。

P.S 除非您“确定”源数据始终是四舍五入到精确“分钟”的日期,否则您可能希望采用与获取离散“日”相同的日期四舍五入数学。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mongoose 找到一个并推送到文档数组 的相关文章

  • javascript中文本区域限制每行的字符数

    我试图用 javascript 限制文本区域中每行的字符数 我在这里看到了一些例子 但并不完全符合我的要求 我写了一些东西 只有当你每次添加超过限制时才可以 换句话说 我每行有 10 个字符的限制 如果你总是输入至少 10 个字符就可以正常
  • 解释 javascript 中的奇怪行为

    我在推特上看到了这个 我也无法解释 定义一个onload函数按以下两种方式工作 1 JSFiddle http jsfiddle net 6rq9k 2 JSFiddle http jsfiddle net 6rq9k 1
  • Angular - Safari 无法正确显示 DOM

    我是 Angular 的新手 使用 Angular 4 我尝试通过在关联的组件类文件中设置属性来更新特定元素 但是 除非我尝试强制重新绘制网页 通过调整窗口大小等 否则页面不会更新 我打开检查器 看到 DOM 已更改 但显示与元素检查器中的
  • Sequelize 4.3.2 n:m(多对多)关联:未处理的拒绝 SequelizeEagerLoadingError

    我有 3 个模型 用户 项目 UserProject module exports function sequelize DataTypes var User sequelize define User title DataTypes ST
  • jquery:如何检查div中的所有单选按钮是否被选中

    我的 html 看起来像这样 div div
  • JQuery 可排序嵌套可排序 div

    这个问题与这个有关Nest jQuery UI 可排序 https stackoverflow com questions 19129476 nest jquery ui sortables 但我无法解决我的问题 问题是 我有一个包含项目的
  • Backbone.js 与 Google 地图 - 有关此问题和侦听器的问题

    我有一个为 Google Maps v3 创建的模块 我正在尝试将其转换为 Backbone js 视图构造函数 到目前为止 这是我的视图模块 我将解释代码后遇到的问题 pg views CreateMap Backbone View ex
  • 如何在WebBrowser控件中注入Javascript?

    我试过这个 string newScript textBox1 Text HtmlElement head browserCtrl Document GetElementsByTagName head 0 HtmlElement scrip
  • 设置股票数据 Highcharts xAxis 的格式

    我已经浏览了需要为 xAxis 属性设置的 Highcharts 选项来格式化时间标签 但没有运气了解这对于这种情况到底是如何工作的 我在白天 盘中 检索了股票的动态数据 我需要显示这些数据 因为检索的数据每天从 9 30 开始到 17 0
  • heroku node.js bash:节点:找不到命令

    在 cedar stack 上的 heroku 上部署我的应用程序似乎存在一个奇怪的问题 我的节点进程甚至没有被调用 我的Proc文件如下 web node web js 和我的 package json 文件 name fuuzik ve
  • 测量填写部分的时间 - 谷歌表单

    我正在尝试使用谷歌表单进行研究调查问卷 对于某些部分 我想自动测量用户填写所需的时间 谷歌表单中没有这样的选项 我尝试复制表单源 并用 javascript 填充时间 但它不起作用 跨源问题 未能成功托管复制的表单 如何做到 我如何衡量回答
  • 将数字限制为段的最优雅的方法是什么?

    比方说x a and b是数字 我需要限制x到段的边界 a b 换句话说 我需要一个钳位功能 https math stackexchange com q 1336636 clamp x max a min x b 有人能想出一个更易读的版
  • 国外收藏的查找和排序

    所以我有一个收藏users 并且此集合中的每个文档以及其他属性都有另一个集合中文档的 id 数组 workouts 集合中的每个文档workouts有一个名为date 这就是我想要得到的 对于特定用户 我想要获取属于该用户的锻炼的 work
  • 如何按值删除数组中的多个项目?

    我正在尝试做一个removeAll 函数 它将删除具有该特定值 而不是索引 的数组的所有元素 当我们对循环进行任何更改时 棘手的部分就出现了 索引往往会移动 使其很难像我们想要的那样工作 并且每次更改时都重新启动循环 这在大数组上效率非常低
  • 替换打字稿中字符串中字符的所有实例?

    我正在尝试用 x 字符替换电子邮件中的所有句号 例如 电子邮件受保护 cdn cgi l email protection 将变为 myxemail emailxcom 电子邮件设置为字符串 我的问题是它不只是替换句号 而是替换每个字符 所
  • 使用 Javascript 检测 Pepper (PPAPI) Flash

    我们使用的是专有的文档查看器 它与某些 Chrome 版本中的 Pepper 版本的 Flash 配合得不太好 所以我希望能够检测到它并重定向到不同格式的相同内容 由于这个版本似乎落后于 NPAPI 版本 所以我一直在使用闪光检测 http
  • Java 驱动程序相当于 JavaScript shell 的 Object.bsonsize( doc )?

    我想知道 Java 驱动程序相当于 Mongo JavaScript shell 的 Object bsonsize doc 方法 例如 执行以下操作的 Java 代码是什么 bobk mbp bobk mongo MongoDB shel
  • 通过ajax执行后期操作时如何克服CORS重定向问题?

    我可以通过外部登录表单中的 post 方法类型提交表单来登录 roundcube 实例 托管在另一台服务器上 我收到此错误 通过 ajax 签名时 XMLHttpRequest 无法加载https 192 168 0 7 mail http
  • 将 javascript 变量作为参数传递给 @url.Action()

    是否可以将javascript变量作为参数传递给 url Action 因为据我所知可能存在服务器和客户端问题 我的要求是我必须根据过滤器下载文件 并进行ajax调用不适用于下载文件 所以我对 url Action 进行了编码 但无法实现这
  • 如何设置javascript对象数组中所有对象的特定属性值(lodash)

    我有以下对象数组 var arr id a1 guid sdfsfd value abc status active id a2 guid sdfsfd value def status inactive id a2 guid sdfsfd

随机推荐

  • 如何在 VSTS 自动构建中对私有 Github 子模块进行身份验证?

    我有一个托管在 VSTS 上的存储库 该存储库有一个私有 github 存储库作为子模块 我启用了签出子模块 使用托管 MacOS 池运行构建 由于无法通过 github 身份验证而失败 2018 06 26T23 06 55 802947
  • 如何配置Neo4j嵌入来运行apoc程序?

    我已经使用最新的 spring 1 5 版本 spring data neo4j 4 2 和 ogm 驱动程序设置了 Neo4j 配置使用没有 URI 的嵌入式驱动程序 因此是临时数据库存储 这是 spring Configuration
  • 使用 iText 打开 PDF 时自动打开打印对话框

    我需要能够在打开 pdf 时自动提供打印对话框 我需要使用 javascript 来完成此操作 我想知道我是否可以使用 iText 附加所述 javascript 这样做对我来说会更干净 因为我目前已经在使用 iText 库 否则有更好的方
  • Spring Security 正在重定向到生产服务器上的本地主机

    我有一个安装了 spring security core 插件的 grails 应用程序 本地一切正常 我部署到临时服务器 一切正常 我部署到我们的生产服务器 它是我们的临时服务器的镜像 我可以很好地访问未受保护的页面 但是 当 Sprin
  • “你调用的对象是空的?” [复制]

    这个问题在这里已经有答案了 如果文本框的文本正确 则尝试显示其他形式 当我调试时 我收到一条错误消息 对象引用未设置到对象的实例 代码如下 OK is OK button MainForm is the form I m trying to
  • html/javascript 中长时间运行的代码

    我需要在单击按钮时在浏览器中运行算法 用 javascript 编码非常复杂 而且速度会很慢 有没有推荐的架构 理想情况下 我想用 C 或 Python 对其进行编码 但我想不可能在单击按钮时在浏览器中运行它 那么 我的下一个最佳选择是什么
  • Highcharts 不显示所有类别

    我正在使用 HighCharts 但我不明白为什么如果 yAxis 中没有数据 它不会在 xAxis 中显示类别 我检查了 API 文档 showEmpty 等于 true 默认值 尽管类别多于数据 如何显示所有类别 My js userC
  • 按特定 id 过滤 Ext.data.Store 会返回多个结果

    我正在尝试按演出 ID 过滤我的试镜列表 但当演出 ID 为 1 时 所有演出 ID 为 1x 的试镜都会被返回 下面是我的代码 试镜型号 Ext regModel Audition fields name id type integer
  • 解释 ANOVA 表的 R 重要性代码?

    测试数据框 gt foo x y z 1 0 191 0 324 0 620 2 0 229 0 302 0 648 3 0 191 0 351 0 626 4 0 229 0 324 0 630 5 0 152 0 374 0 656 6
  • 更改 DateTimePicker 控件中的周显示

    在 vb net 或 c 应用程序的 winforms 环境中使用传统的 DateTimePicker 控件 我需要将星期的显示方式从正常的星期日到星期六更改为星期二到星期一 我搜索了 Google 和 Stack 但没有发现任何相关内容
  • js 处理完成时的基本 Javascript 加载消息

    我确信这个问题之前已经被问过 1000 次了 基本上我想做的就是更改页面元素的内容以在我的其他 javascript 代码 相当资源密集型 完成时显示加载消息 问题是消息直到 其他 JS 处理 完成后才显示 从而完全违背了其目的 一个简化的
  • 使用 Python Windows 获取 CPU 和 GPU 温度

    我想知道是否有办法在 python 中获取 CPU 和 GPU 温度 我已经找到了Linux的方法 使用psutil sensors temperature 我想找到一种适用于 Windows 的方法 一种查找 Mac OS 温度的方法也将
  • 使用 re.sub() 将模式大写并在该模式之前添加一些文本

    这篇文章是后续我之前的问题 所以我有以下字符串 string A 1 e 1 X 我想创建一个函数来输出一个包含所有内容的字符串小写字母序列 后面没有括号在前面用大写字母写成的字符串中Math 例如 1 e 会回来 1 Math E 5 2
  • 为什么 pyauto gui 和 Pycharm 不适合我?

    import pyautogui pyautogui PAUSE 1 pyautogui FAILSAFE True pyautogui click 274 783 我在 Mac 上运行 Pycharm 我尝试从解释器安装 pyautogu
  • 浏览器工具中的 [] 与 [{...}],但两者具有相同的对象

    如果你看一下图片 两个数组都由相同类型的对象组成 第一个我使用空数据作为占位符创建它 但第二个我使用来自服务器的数据创建它 writeValue v any console log aaa console log v console log
  • HTML 表格转 JSON

    我需要获取表行并将其转换为 JSON 有任何想法吗 我这里有这段代码 但它不起作用 function tableToJSON tableID return tableID tr map function row return row des
  • 如何指定在 Git 上执行 shell 命令时使用的私有 SSH 密钥?

    也许是一种相当不寻常的情况 但我想指定一个在执行 shell 时使用的私有 SSH 密钥 git 来自本地计算机的命令 基本上是这样的 git clone email protected TheUser TheProject git key
  • 构建一个表,其中的值将连续变量分为两组

    我正在寻求你的帮助 我试图将连续变量分为两组 我用这个例子来说明我想要做什么 x data frame v1 c 1 1 2 2 3 4 5 6 9 9 11 2 4 45 67 89 1 1 5 5 5 6 6 6 9 9 9 11 11
  • PHP 是否有类似于 .NET 的 DataSet 的构造?

    我怎样才能实现DataSet在 PHP 中 如 NET 我希望这个类只从数据库读取数据一次 然后我应该能够使用这些数据 而无需再次连接到 MySQL 来运行查询 select from user 当我在DataSet数据是从内存中获取的 我
  • Mongoose 找到一个并推送到文档数组

    我是 MongoDB 和 Mongoose 的新手 我正在尝试使用它来保存股票报价以进行日间交易分析 所以我想象了这个架构 symbolSchema Schema name String code String quoteSchema Sc