【问题标题】:before.insert / Meteor extension / mongoObservable / get last object from mongoDB = "undefined"before.insert / Meteor 扩展 / mongoObservable / 从 mongoDB = "undefined" 获取最后一个对象
【发布时间】:2019-01-18 11:05:49
【问题描述】:

我在problems.collection.ts 中有这个插入方法的代码扩展。我需要找到最后插入的对象,获取 lastId 并增加它。

每个对象都有自己的唯一 ID,但我想在每个对象中创建更合适的“problemSecondId”,并将在我的应用程序中呈现给用户。

因此,当我在集合中创建第一个“问题”时,我在变量“lastProblem”中得到console.log“未定义”,并且使用“problemSecondId:1”创建对象。当我创建第二个“问题”时,我再次得到“未定义”,第二个“问题”也是用“problemSecondId:1”创建的!!!我尝试了很多东西。

代码的行为,查询“findOne”返回“未定义”所以我认为,那个错误是在查询中,或者可能的错误可能是集合“问题”不是 Mongo.Collection 而是 MongoObservable.Collection...?有人可以帮助我吗?谢谢。

import { MongoObservable } from "meteor-rxjs";
import { Problem } from "../models/problem.model";
import { Observable } from "rxjs";
import { Mongo } from "meteor/mongo";


class ProblemCollection extends Mongo.Collection {
    insert(problem, callback) {
      if (!problem.problemSecondId) {
        let lastProblem = Problems.findOne({}, { sort: { problemSecondId: -1 }});
        console.log(lastProblem);
        if (lastProblem){
          let lastProblemId = lastProblem.problemSecondId++;
          problem.problemSecondId = lastProblemId;
        } else {
          problem.problemSecondId = 1;
        }

      }

      return super.insert(problem, callback);
    }
  }



let problems = new ProblemCollection("problems");

export const Problems = new MongoObservable.Collection<Problem>(problems);


function loggedIn() {
    return !!Meteor.user();
  }

Problems.allow({
    insert: loggedIn,
    update: loggedIn,
    remove: loggedIn
});

【问题讨论】:

  • 您好,有几件事:无需删除问题并提出几乎相同的问题。如果您有什么要添加的,您可以编辑您现有的问题。现在,关于这个话题:您是否绝对确定您在lastProblem 中的查询结果第二次是undefined,或者您是否从您的第二个problemlastProblemId 也为1 的事实中推断出这一点?因为我认为您的查询没有任何问题,但是您的代码存在问题,会导致确切的行为(两个文档都带有 lastProblemId1)。
  • 谢谢回答。我读到的关于“findOne”的内容(它确实是 .fetch()[0] ),所以这应该返回某些对象,但在 console.log 中我在这两种情况下都看到未定义,所以我认为它是在代码的“else”部分执行的.是的,我在数据库中检查过,每个创建的问题都有“problemSecondId:1”
  • 您是否在服务器控制台中检查 console.log(lastProblem) 未定义?
  • 我在both/collections/problems.collection.ts中有上面的代码。本例中的 console.log 在浏览器控制台中显示输出。所以我假设,我应该将代码复制到 server/imports/main.ts ???或者 server/imports/publications/problems.ts ??
  • 检查终端控制台,看看它是否也显示未定义。它在浏览器控制台中未定义的事实可能只是您没有在出版物中发送此数据

标签: angular mongodb meteor insert hook


【解决方案1】:

这似乎是滥用后缀 increment (++) 运算符的一个很好的例子。

let x = 5;
let y = x++; // x = 6, y = 5

涉及后缀运算符的表达式在增量之前计算为值。

问题是,一开始并没有真正的需要。您无需增加lastProblemproblemSecondId 属性,因为您只需设置problem 对象的相同属性即可。

只需使用:

problem.problemSecondId = lastProblem.problemSecondId + 1;

在我看来,这会更清晰,并且具有实际做你想做的事情的优势。

您的查询在客户端返回undefined这一事实并不一定意味着服务器上也是如此,因为客户端上可用的数据可能无法反映数据库内容。

作为旁注,考虑到您可能会遇到竞争条件,其中 2 个 problems 是在附近创建的,并且两者都可以获得相同的 problemSecondId,因为操作组合 (@987654331 @ 和 update) 不是原子的,也没有使用锁。

【讨论】:

    【解决方案2】:

    我在代码中添加了“Meteor.isServer”条件以仅在服务器上执行代码。结果是我在控制台和终端中没有输出(并且在 MongoDb 中创建了对象并且“problemSecondId”完全丢失)。所以我对解决这个问题非常不满意。不可能有问题,问题.collection.ts 位于meteort/both/collections/... 我认为,这是正确的,因为收集(客户端和服务器)都使用。编辑代码如下:

    import { MongoObservable } from "meteor-rxjs";
    import { Problem } from "../models/problem.model";
    import { Observable } from "rxjs";
    import { Mongo } from "meteor/mongo";
    
    
    class ProblemCollection extends Mongo.Collection {
    
          insert(problem, callback) {
    
                  if (Meteor.isServer) {
    
                        if (!problem.problemSecondId) {
                          let lastProblem = Problems.findOne({}, { sort: { problemSecondId: -1 } });
                          console.log(lastProblem);
                          if (lastProblem) {
                            console.log('xxx');
                            let lastProblemId = lastProblem.problemSecondId + 1;
                            problem.problemSecondId = lastProblemId;
                          } else {
                            console.log('yyy')
                            problem.problemSecondId = 1;
                          }
    
                        }
                  }
    
            return super.insert(problem, callback);
    
          }
    
    
     }
    
    
    
        let problems = new ProblemCollection("problems");
    
        export const Problems = new MongoObservable.Collection<Problem>(problems);
    
    
        Problems.allow({
          insert: loggedIn,
          update: loggedIn,
          remove: loggedIn
        });
    
    
    
        function loggedIn() {
            return !!Meteor.user();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-17
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      相关资源
      最近更新 更多