我有一个JS自定义类型“Piece”,并根据doc将其作为自定义数据类型添加到EJSON。我将它存储在通用对象的集合“PieceHolders”中(因为顶级对象不能是自定义类型),形式为:{piece:aPiece}。
在我的Meteor插入方法中,我首先要根据名称和作曲家检查重复,例如 PieceHolders.findOne({“piece.name”:“Sample1”,“piece.composer”:“PJD”}); 现在这在客户端上运行正常,但在服务器上运行不正常 - 因此我最终得到了重复项。为什么? 因为Mongo doc看起来像这样: {“piece”:{“EJSON $ type”:“Piece”,“EJSON $ value”:{“EJSONname”:“Sample1”,“EJSONcomposer”:“PJD”,... 而且我没有相应地搜索服务器。
我正在考虑使用变换,但是在查找之后按摩数据,而不是之前。不用说,同样的搜索需要在客户端和服务器上都能正常工作。
我需要做什么?
答案 0 :(得分:0)
要匹配包含自定义类型的字段,请在选择器中使用自定义类型的实例:
PieceHolders.findOne({
piece: new Piece({name: 'Sample 1', composer: 'PJD'})
});
上述查询将使用自定义类型匹配插入的文档:
PieceHolders.insert({
piece: new Piece({name: 'Sample 1', composer: 'PJD'})
});
确保在服务器和客户端
上声明自定义类型Piece = function (obj) {
this.name = obj && obj.name;
this.composer = obj && obj.composer;
}
Piece.prototype = {
// typeName: function ...
// clone: function ...
// equals: function ...
toJSONValue: function () {
return {
name: this.name,
composer: this.composer
};
}
};
EJSON.addType("Piece", function fromJSONValue(value) {
return new Piece(value);
});
正如OP所指出的,上述解决方案不允许查询服务器上EJSON自定义类型的选定属性。在这种情况下,最好在Mongo集合上使用转换,而不是添加EJSON类型。
假设我们希望在使用集合 .findOne()或 cursor piece字段作为Piece
对象返回> .fetch()。
首先,评论或删除与EJSON.addType
相关的Piece
声明。这样做允许我们将Piece
个对象作为JSON对象存储在数据库中,而不是它的EJSON表示。
// Comment or remove lines below
//
// EJSON.addType("Piece", function fromJSONValue(value) {
// return new Piece(value);
// });
其次,为包含Piece
个对象的任何Mongo集合添加或修改转换选项。通过调用其构造函数替换包含Piece
个对象的任何字段。
PieceHolders = new Mongo.Collection('PieceHolders', {
transform: function (doc) {
if (doc.piece) doc.piece = new Piece(doc.piece);
return doc;
}
});
通过插入新文档并检索它来进行测试。
PieceHolders.insert({
piece: new Piece({name: 'name1', composer: 'Tom'})
});
PieceHolders.insert({
piece: new Piece({name: 'name2', composer: 'Tom'})
});
PieceHolders.find({'piece.composer': 'Tom'}).fetch();
/* Should return the 2 documents we inserted!
[
{ piece: { name: 'name1', composer: 'Tom' }, _id: 'YFRiWHsTjQbFL7YSb' },
{ piece: { name: 'name2', composer: 'Tom' }, _id: 'd4SoeLfWrpRyXBe9y' }
]
*/
PieceHolders.findOne().piece instanceof Piece
/* Should return true! */
我们可以继续向Piece
类添加更多属性,并在需要时更新其toJSONValue方法。