【问题标题】:How can I add a two column unique id to the mongodb in a meteor app?如何在流星应用程序中向 mongodb 添加两列唯一 ID?
【发布时间】:2012-04-27 09:33:08
【问题描述】:

我正在尝试在流星应用程序中的基础 mongodb 上创建一个两列唯一索引并且遇到了问题。我在流星文档中找不到任何内容。我已经从 chrome 控制台尝试过。我从 term 开始尝试过,甚至试图将 mongod 指向 .meteor 内的 /db/ 目录。我试过了

Collection.ensureIndex({first_id: 1, another_id: 1}, {unique: true}); 变体。

我希望能够防止流星应用程序 mongo 集合中出现重复条目​​。

想知道是否有人发现了这一点?

我回答了我自己的问题,真是个菜鸟。

我想通了。

  1. 启动流星服务器

  2. 打开第二个终端并输入meteor mongo

然后创建您的索引...例如,我为 thumbsup 和 thumbsdown 类型系统的记录做了这些。

db.thumbsup.ensureIndex({item_id: 1, user_id: 1}, {unique: true})
db.thumbsdown.ensureIndex({item_id: 1, user_id: 1}, {unique: true})

现在,只需要找出一个引导安装设置,它会在推送到 prod 时而不是手动创建这些设置。

【问题讨论】:

  • 我在看到您的编辑之前发布了我的答案,但请注意,仅在服务器端启用索引,您的用户会认为他们给出了多个支持,即使这些支持实际上并没有被保存。因此,作为一种解决方法,最好在插入之前进行查询。
  • 如果您将自己的答案与问题分开发布会更好。更清晰。

标签: javascript mongodb meteor


【解决方案1】:

Collection._ensureIndex(index, options)

在 Meteor 源代码中搜索,我发现了一个绑定到 ensureIndex 的名为 _ensureIndex。 对于单键基本索引,您可以遵循 packages/accounts-base/accounts_server.js 的示例,该示例在 Meteor 上强制使用唯一用户名:

Meteor.users._ensureIndex('username', {unique: 1, sparse: 1});

对于多键“复合”索引:

Collection._ensureIndex({first_id:1, another_id:1}, {unique: 1});

前面的代码,当放置在服务器端时,确保设置了索引。

警告

注意 _ensureIndex 实施警告:

我们稍后会实际设计一个索引 API。现在,我们只是通过 一直到 Mongo,但要同步。

【讨论】:

  • 知道space: 1 是什么意思吗?
  • 你的意思是sparse?当不是给定集合中的所有条目都设置了此字段时。所以索引是“稀疏的”。在这种情况下,并非所有 Meteor.user 都需要设置用户名
【解决方案2】:

根据docs“Minimongo 目前没有索引。这很快就会到来。”查看 Collection 上可用的方法,没有ensureIndex

您可以为 mongo shell 运行 meteor mongo 并在服务器端启用索引,但 Collection 对象仍然不知道它们。因此,该应用程序将允许您将多个实例添加到集合缓存中,而在服务器端,其他插入将静默失败(错误被写入输出)。当您进行硬页面刷新时,应用程序将与服务器重新同步

所以你现在最好的选择可能是做这样的事情:

var count = MyCollection.find({first_id: 'foo', another_id: 'bar'}).count()
if (count === 0)
    MyCollection.insert({first_id: 'foo', another_id: 'bar'});

这显然不理想,但工作正常。您还可以在服务器上的 mongodb 中启用索引,因此即使在竞争条件下,您实际上也不会得到重复记录。

【讨论】:

  • 谢谢@danny,我刚刚注意到这篇文章出现时的这种行为。
  • 顺便说一句,对于任何想知道的人,我都实现了。为安全起见,前端的上述逻辑和后端的唯一索引。
  • 这个解决方法似乎仍然不理想。如果您在应用程序从服务器提取所有数据之前调用MyCollection.find 怎么办?
  • 另一种模式是使用 Meteor 方法进行插入。类似于: Meteor.call('addAFoo', fooData, function() {});
【解决方案3】:

Smartpackage aldeed:collection2 支持唯一索引以及模式验证。验证将同时发生在服务器和客户端(反应性地),因此您可以对客户端上的错误做出反应。

【讨论】:

【解决方案4】:

实际上,为什么不在服务器上使用带有 Meteor.method 的 upsert 并且您也可以使用 ts 发送也跟踪它: // 仅限服务器

Meteor.methods({
 add_only_once = function(id1,id2){
   SomeCollection.update(
     {first_id:id1,another_id:id2},{$set:{ts:Date.now()}},{upsert:True});
 }
});

// 客户端

Meteor.call('add_only_once',doc1._id, doc2._id);

//在服务器上运行的实际代码

if(Meteor.is_server) {
    Meteor.methods({
        register_code: function (key,monitor) {
             Codes.update({key:key},{$set:{ts:Date.now()}},{upsert:true});
        }
     ...

【讨论】:

  • 根据 docs.meteor.com upsert 尚不支持 Mongo/MiniMongo 的东西。否则会很好。
  • 更新插入工作?非常好的消息,代码现在可以工作,也许最新版本的 Meteor 解决了这个问题?我不知道,几周没用 Meteor。
  • 我不知道 upsert 选项是在服务器上实现的不存在..
  • 首先,截至 2013 年 8 月 12 日,不支持 upsert。其次,您可以将任何内容放入第三组花括号中,它会被忽略(刚刚在 064 上测试过)
  • 从 0.6.6 开始提供更新广告
猜你喜欢
  • 1970-01-01
  • 2015-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多