Meteor 流星自定义类型查找
我有一个JS自定义类型块,并根据文档将其作为自定义数据类型添加到EJSON。我将其存储在泛型对象的集合中,因为顶级对象不能是形式为{piece:apece}的自定义类型 在我的Meteor insert方法中,我首先要基于名称和编写器检查重复项,例如 piecholders.findOne{piece.name:Sample1,piece.composer:PJD}; 现在,这在客户机上可以很好地工作,但在服务器上却不行——因此我最终得到了重复的结果。为什么? 因为Mongo文档看起来像这样: {piece:{EJSON$type:piece,EJSON$value:{EJSONname:Sample1,EJSONcomposer:PJD。。。 我没有相应地搜索服务器 我曾考虑使用转换,但这会在查找之后而不是之前对数据进行处理。不用说,同样的精确搜索需要在客户端和服务器上进行Meteor 流星自定义类型查找,meteor,Meteor,我有一个JS自定义类型块,并根据文档将其作为自定义数据类型添加到EJSON。我将其存储在泛型对象的集合中,因为顶级对象不能是形式为{piece:apece}的自定义类型 在我的Meteor insert方法中,我首先要基于名称和编写器检查重复项,例如 piecholders.findOne{piece.name:Sample1,piece.composer:PJD}; 现在,这在客户机上可以很好地工作,但在服务器上却不行——因此我最终得到了重复的结果。为什么? 因为Mongo文档看起来像这样:
我需要做什么?要匹配包含自定义类型的字段,请在选择器中使用自定义类型的实例:
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类型
假设我们希望在使用collection.findOne或cursor.fetch时将文档的片段字段作为片段对象返回
首先,注释或删除与Piece相关的EJSON.addType声明。这样做允许我们将Piece对象作为JSON对象存储在数据库中,而不是它的EJSON表示
// Comment or remove lines below
//
// EJSON.addType("Piece", function fromJSONValue(value) {
// return new Piece(value);
// });
其次,添加或修改任何包含工件对象的Mongo集合的transform选项。使用对其构造函数的调用替换任何包含工件对象的字段
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方法。您现有的解决方案对我没有帮助,因为Piece不仅仅是名称和编写器,我只想在名称和编写器都匹配的情况下定义一个副本。但Piece也可以有catalogReference,以及一系列度量值等。您的方法只有在所有内容都匹配时才有效,而这不是我想要的。或者说,我想找到某个作曲家的所有作品。我已经扩展了答案。如果有帮助,请告诉我!它实际上工作得很好,而且我不再需要“holder”通用对象包装器,因为“顶级对象不能被复制”“tom types”只是对EJSON的限制,而不是JSON。但我想知道什么时候我会对自定义类型使用EJSON.addType声明。就我个人而言,作为核心开发人员,我认为EJSON自定义类型是个坏主意,很少能解决问题。尤其是不将它们存储在数据库中。