Meteor 1.0 - 使用变量作为键的 Mongo 查询,包括$inc
Meteor 1.0 - Mongo queries using variables as key, including $inc
我正在使用一个大型数据集,该数据集需要有效地处理其Mongo查询。该应用程序使用福特-富尔克森算法来计算建议并在多项式时间内运行,因此效率非常重要。语法是 ES6,但一切都基本相同。
这是我正在使用的数据的近似值。一个项目数组和一个项目与其他项目匹配的项目:
let items = ["pen", "marker", "crayon", "pencil"];
let match = "sharpie";
最终,我们将迭代match
并将配对的权重增加 1。因此,在完成该函数后,我的理想数据如下所示:
{
sharpie: {
pen: 1,
marker: 1,
crayon: 1,
pencil: 1
}
}
为了进一步详细说明,每个键旁边的值是该关系的weight
,也就是说,这些项目配对在一起的次数。我希望发生的事情是这样的:
// For each in the items array, check to see if the pairing already
// exists. If it does, increment. If it does not, create it.
_.each(items, function(item, i) {
Database.upsert({ match: { $exist: true }}, { match: { $inc: { item: 1 } } });
})
当然,问题在于Mongo不允许括号表示法,也不允许变量名作为键(match
)。据我所知,另一个问题是 Mongo 在深度嵌套$inc
运算符('The dollar ($) prefixed field ''$inc'' in ''3LhmpJMe9Es6r5HLs.$inc'' is not valid for storage.' }
)方面也存在问题。
我能做些什么来尽可能少的查询中做到这一点?我愿意接受建议。
编辑
我尝试创建对象以传递到 Mongo 查询中:
_.each(items, function(item, i) {
let selector = {};
selector[match] = {};
selector[match][item] = {};
let modifier = {};
modifier[match] = {};
modifier[match]["$inc"] = {};
modifier[match]["$inc"][item] = 1
Database.upsert(selector, modifier);
不幸的是,它仍然不起作用。$inc
会破坏查询,它不会让我深入超过 1 级来更改任何内容。
溶液
这是我最终实现的功能。它就像一个魅力!谢谢马特。
_.each(items, function(item, i) {
let incMod = {$inc:{}};
let matchMod = {$inc:{}};
matchMod.$inc[match] = 1;
incMod.$inc[item] = 1;
Database.upsert({node: item}, matchMod);
Database.upsert({node: match}, incMod);
});
我认为问题来自您的ER模型。 sharpie
不是一个独立的实体,尖刀是一个项目。1 项与其他项之间的关系是,1 项具有许多项(1:M 递归),并且每个项配对都有一个权重。
完全规范化,你会有一个项目表和一个权重表。项目表将包含项目。权重表将具有类似于 item1
、 item2
、 weight
的内容(这样做,您可以有不对称的权重,例如 sharpie:pencil = 1
, pencil:sharpie = .5
,这在计算 FFA 中的推回时很有用,但我认为这不适用于您的情况。
太好了,现在让我们把它蒙哥化。
当我们说 1 个项目有很多项目时,"许多"可能不会超过几千个(想想 16MB 的文档上限)。这意味着它实际上是一对一,这意味着我们可以使用子文档或字段来嵌套数据。
那么,让我们看看这个架构!
doc =
{
_id: "sharpie",
crayon: 1,
pencil: 1
}
我们看到了什么? sharpie
不是键,而是值。这使一切变得容易。我们将项目保留为字段。我们不使用对象数组的原因是因为它更快、更干净(无需遍历数组以找到匹配的_id
)。
var match = "sharpie";
var items = ["pen", "marker", "crayon", "pencil"];
var incMod = {$inc:{}};
var matchMod = {$inc:{}};
matchMod.$inc[match] = 1;
for (var i = 0; i < items.length; i++) {
Collection.upsert({_id: items[i]}, matchMod);
incMod.$inc[items[i]] = 1;
}
Collection.upsert({_id: match}, incMod);
这是容易的部分。困难的部分是弄清楚为什么要将FFA用于建议引擎:-P。
- 如何在 Meteor 中的 Mongo 查询中使用变量作为字段名称
- Meteor:在模板接受Mongo查询结果之前修改它的最佳实践
- JS/Mongo在JSON中使用多个$或进行查询
- 当查询返回对象时,Express Mongo回调返回undefined
- 按时钟范围查询mongo文档-正向和反向
- 如何使用 i18n 构建对 Mongo 的查询
- Mongo 查询以从集合数组返回特定值
- Javascript 到 Mongo 查询 passthru.安全?不好的做法
- 如何根据 Mongo 中集合中的布尔值有条件地查询密钥
- 客户端查询延迟 - Meteor's Mongo Collections
- 流星:在Mongo数据库查询上隐藏/显示模板
- 使用猫鼬查询 mongo 中集合的命名文本索引
- 使用 javascript 从 Mongo 集合中查询数据
- Mongo查询今天是否's的日期在另外两人之间
- 如何使用本机节点驱动程序在节点服务器上执行mongo查询字符串
- 嵌套字段中的Mongo查询
- Mongo查询没有't不包括我的筛选子句
- 如何使用Node.js查询Mongo
- 基于匹配或正则表达式的查询字符串查询Mongo
- 不能让我的地理空间查询工作.在Node中查询Mongo