通过Meteor从阵列中拉出一个条目

时间:2015-08-06 10:15:30

标签: javascript mongodb meteor mongodb-query

我在Meteor 1.1.0.2应用程序中使用了以下(简化的)SimpleSchema架构:

Tickers.attachSchema(
    new SimpleSchema({
        entries: {
            type: [TickerEntries],
            defaultValue: [],
            optional: true
        }
    })
);

TickerEntries = new SimpleSchema({
    id: {
        type: String,
        autoform: {
            type: "hidden",
            label: false,
            readonly: true
        },
        optional: true,
        autoValue: function () {
            if (!this.isSet) {
                return new Mongo.Collection.ObjectID()._str;
            }
        }
    },
    text: {
        type: String,
        label: 'Text'
    }
};

在数据库中,我有以下条目:

{
    "_id" : "ZcEvq9viGQ3uQ3QnT",
    "entries" : [
        {
            "text" : "a",
            "id" : "fc29774dadd7b37ee0dc5e3e"
        },
        {
            "text" : "b",
            "id" : "8171c4dbcc71052a8c6a38fb"
        }
    ]
}

我想删除ID指定的条目数组中的一个条目。

如果我在meteor-mongodb-shell中执行以下命令,它可以正常工作:

db.Tickers.update({_id:"3TKgHKkGnzgfwqYHY"}, {"$pull":{"entries": {"id":"8171c4dbcc71052a8c6a38fb"}}})

但问题是,如果我要在Meteor中做同样的事情,它就不起作用了。这是我的代码:

Tickers.update({id: '3TKgHKkGnzgfwqYHY'}, {$pull: {'entries': {'id': '8171c4dbcc71052a8c6a38fb'}}});

我还尝试过以下方法:

Tickers.update('3TKgHKkGnzgfwqYHY', {$pull: {'entries': {'id': '8171c4dbcc71052a8c6a38fb'}}});

这些命令都没有给我一个错误,但是他们不会从我的文档中删除任何内容。

是否有可能,$pull命令没有得到正确支持,或者我在某个地方犯了错误?

提前致谢!

编辑: 我发现了问题,在我的描述中无法看到,因为我已经简化了我的架构。在我的应用中,timestamp中有一个额外的属性TickerEntries

TickerEntries = new SimpleSchema({
    id: {
        type: String,
        optional: true,
        autoValue: function () {
            if (!this.isSet) {
                return new Mongo.Collection.ObjectID()._str;
            }
        }
    },
    timestamp: {
        type: Date,
        label: 'Minute',
        optional: true,
        autoValue: function () {
            if (!this.isSet) { // this check here is necessary!
                return new Date();
            }
        }
    },
    text: {
        type: String,
        label: 'Text'
    }
});

感谢Kyll的提示,我创建了一个Meteorpad并发现autovalue函数导致问题。

我现在已将功能更改为以下代码:

autoValue: function () {
    if (!this.isSet && this.operator !== "$pull") { // this check here is necessary!
        return new Date();
    }
}

现在它正在发挥作用。看来,在拉动一个项目/对象的情况下返回一个autovalue值,它取消了pull操作,因为该值没有设置为返回值(所以timestamp属性保留旧值但是isn&# 39;拉了。)

根据Meteorpad测试它(只需在autovalue函数中注释掉运算符的检查):http://meteorpad.com/pad/LLC3qeph66pAEFsrB/Leaderboard

谢谢大家的帮助,你的所有帖子对我都很有帮助!

2 个答案:

答案 0 :(得分:5)

对于基本的流星应用程序,我称之为“bunk”。如果您创建一个全新的项目并只是定义集合,那么$pull运算符将按预期工作:

<强>控制台:

meteor create tickets
cd tickets
meteor run

然后打开一个shell并插入你的数据:

meteor mongo

> db.tickets.insert(data)   // exactly your data in the question

然后只生成一些基本代码和模板:

<强> tickers.js

Tickers = new Meteor.Collection("tickers");

if (Meteor.isClient) {

  Template.body.helpers({
    "tickers": function() {
      return Tickers.find({});
    }
  });

}

if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup
  });
}

<强> tickers.html

<head>
  <title>tickers</title>
</head>

<body>
  <h1>Welcome to Meteor!</h1>

  <ul>
    {{#each tickers}}
      {{> ticker}}
    {{/each}}
  </ul>

</body>

<template name="ticker">
  <li>
    {{_id}}
    <ul>
      {{#each entries}}
        {{> entry }}
      {{/each}}
    </ul>
  </li>
</template>

<template name="entry">
  <li>{{ id }} - {{text}}</li>
</template>

应用程序运行正常,因此在浏览器控制台中执行.update()(缩进阅读):

Tickers.update(
    { "_id": "ZcEvq9viGQ3uQ3QnT" },
    { "$pull": { "entries": { "id": "fc29774dadd7b37ee0dc5e3e" } }}
)

该项目将从条目中删除,并且页面将在没有该项目的情况下刷新。所以一切都消失了,就像预期一样。

即使添加SimpleSchemaCollection2软件包,也没有区别:

 meteor add aldeed:simple-schema
 meteor add aldeed:collection2

<强> tickers.js

Tickers = new Meteor.Collection("tickers");

TickerEntries = new SimpleSchema({
  "id": {
    type: String,
    optional: true,
    autoValue: function() {
      if (!this.isSet) {
        return new Mongo.Collection.ObjectID()._str
      }
    }
  },
  "text": {
    type: String
  }
});

Tickers.attachSchema(
  new SimpleSchema({
    entries: { type: [TickerEntries] }
  })
);


if (Meteor.isClient) {

  Template.body.helpers({
    "tickers": function() {
      return Tickers.find({});
    }
  });

}

if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup
  });
}

重新初始化数据并在浏览器控制台中运行相同的命令,一切都保持不变。

检查您自己的操作中的这个或任何输入错误或其他差异,以找出为什么这对您不起作用的线索。

我强烈建议这样做,因为“像这样开始新鲜”会显示预期的行为,如果你看到不同的行为,那么你可能已经安装了另一个插件的问题。

但一般来说,这都有效。

答案 1 :(得分:0)

请注意,如果其他人正在寻找答案。

如果您在SimpleSchema中使用,您有两种选择: 数组字段应标记为可选

arr: {
 type:Array,
 optional:true
}

或者在更新查询中使用getAutoValues: false

Coll.update({}, {$pull: {arr: ''}}, {getAutoValues: false});