【问题标题】:How to force server-side insert on Meteor's collection.insert如何在 Meteor 的 collection.insert 上强制服务器端插入
【发布时间】:2014-11-18 09:29:42
【问题描述】:

我有一个包含 40,000 行的简单 CSV 文件,我正在使用 papa-parse 处理浏览器端。

我正在尝试使用 Discover Meteor 中的技术以及我在谷歌搜索时发现的其他 101 个帖子中的技术将它们一个一个地插入到一个集合中。

40000 非常快地插入浏览器端 - 但是当我检查 mongo 服务器端时,它只有 387 条记录。

最终(通常在 20 秒左右后)它开始插入服务器端。 但是如果我关闭或中断浏览器,已经插入的记录就会明显消失。

如何强制插入到服务器端,或者至少进行监控,以便我知道何时通知用户成功?

我试过 Tracker.flush() 没区别。

我会在 Meteor.method 中进行服务器端插入,但所有服务器端 CSV 库的操作都比客户端复杂(我几乎是所有编程的初学者 :)

谢谢!


这是我的代码的主要部分(在客户端文件夹中):

Template.hello.events({

    "submit form": function (event) {

        event.preventDefault();

        var reader = new FileReader();

        reader.onload = function (event) {

            var csv = Papa.parse(this.result, {header: true});

            var count = 0;

            _.forEach(csv.data, function (csvPerson) {
                count++;
                Person.insert(csvPerson);
                console.log('Inserting: ' + count + ' -> ' + csvPerson.FirstName);
            });

        };

        reader.readAsText(event.target[0].files[0]);
    }
});

控制台输出的最后几行:

Inserting: 39997 -> Joan 
Inserting: 39998 -> Sydnee 
Inserting: 39999 -> Yael 
Inserting: 40000 -> Kirk 

CSV 的最后几行(随机生成的数据):

Jescie,Ayala,27/10/82,"P.O. Box 289, 5336 Tristique Road",Dandenong,7903,VI,mus.Proin@gravida.co.uk
Joan,Petersen,01/09/61,299-1763 Aliquam Rd.,Sydney,1637,NS,sollicitudin@Donectempor.ca
Sydnee,Oliver,30/07/13,Ap #648-5619 Aliquam Av.,Albury,1084,NS,Nam@rutrumlorem.ca
Yael,Barton,30/12/66,521 Auctor. Rd.,South Perth,2343,WA,non.cursus.non@etcommodo.co.uk
Kirk,Camacho,25/09/08,"Ap #454-7701 A, Road",Stirling,3121,WA,dictum.eu@morbitristiquesenectus.com

hello 模板显然是一个简单的表单,只是文件选择和提交。 客户端代码在客户端目录下。 在应用程序根目录的文件中定义的人。 CSV 现在被解析为字符串,以避免复杂性。 插入的记录看起来不错,按名称检索,随便什么。

Person.find().count() 浏览器端在控制台中的结果为 40000。

很高兴发送文件,该文件只有 1.5MB,是随机数据 - 不敏感。

【问题讨论】:

  • 您是否删除了自动发布和/或不安全的软件包?
  • 不,自动发布和不安全仍然存在,这会影响答案吗?
  • 不,只有在您没有自动发布功能的情况下,如果您需要发布和订阅该集合。在客户端创建一个未由服务器发布的集合意味着创建本地浏览器内集合。这可能是在客户端插入所有行的原因,而在服务器上,您只能拥有部分数据,可能来自过去的运行。尝试将 Person 数据库删除到 mongo 中,然后重试导入。如果您在插入后在 mongo 上看到 0 条记录,这意味着您没有在客户端上使用已发布的集合。

标签: collections meteor minimongo


【解决方案1】:

我认为 call() 应该如下工作:

在客户端

Meteor.call("insertMethod",csvPerson);

服务器端的方法

insertMethod: function(csvPerson){
Person.insert(csvPerson);
}

【讨论】:

  • 我最终会像你展示的那样做这个服务器端,但它限制了我在解析库方面的选择。现在我正试图让客户端可靠地工作。我想有一个简单的方法来强制插入,只是还没有找到它:)
  • 那么奇怪的是你的方法不起作用,控制台日志是返回所有记录还是只返回那些插入的记录?
【解决方案2】:

在 Meteor 中,在某些情况下,如果您不传递回调,操作将同步

如果您在服务器上运行代码Person.insert(csvPerson);,操作将是同步而不是异步。取决于你想做什么,你将来可能会遇到严重的问题。在客户端,它不会是同步的,而是异步的。

由于 node.js 是基于事件的服务器,因此单个同步操作可以停止整个系统。您必须真正关注您的同步操作。

对于导入数据,最好的选择是在服务器端内部Meteor.startup(function(){ //import code goes here})

Sindis 提出的解决方案可行,但速度很慢,如果浏览器关闭(出于某种原因),您就不会跟踪已插入的记录。如果你使用Meteor.call("insertMethod",csvPerson);,这个操作会在客户端同步。

初学者场景的最佳选择(不是最佳选择)是:

1- While(您有要插入的记录)

2- 在没有回调的情况下调用 Meteor.call

3- 统计集合中所有插入的字段

4- 将此值保存到 localStorage

5- 返回第 1 步

假设每次插入尝试的插入顺序都相同,则此方法有效。如果您的浏览器出现故障,您始终可以从 localStorage 获取值并跳过该数量的记录。

【讨论】:

  • 谢谢马里奥,一旦我“得到它”,我肯定会做这个服务器端。您的回答有帮助,但是-> 对于当前的解决方案,是否有任何内置方法可以检查客户端或服务器是否有未完成的(异步)操作排队等待处理?理想情况下,可以让我区分普通的 DOM/会话内容和这种类型的 mongo 操作?如果没有,无论如何我都会结束你的回答,但我很想了解我出于教育目的的选择:)
猜你喜欢
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-16
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多