gpt4 book ai didi

javascript - Meteor 1.0 - 使用变量作为键的 Mongo 查询,包括 $inc

转载 作者:可可西里 更新时间:2023-11-01 09:43:25 27 4
gpt4 key购买 nike

我正在处理一个需要高效处理 Mongo 查询的大型数据集。该应用程序使用 Ford-Fulkerson 算法计算推荐并在多项式时间内运行,因此效率极其重要。语法是 ES6,但一切基本相同。

这是我正在处理的数据的近似值。一组项目和一个项目与其他项目匹配:

let items = ["pen", "marker", "crayon", "pencil"];
let match = "sharpie";

最终,我们将遍历 match 并将配对的权重增加 1。因此,在完成该函数后,我的理想数据如下所示:

{
sharpie: {
pen: 1,
marker: 1,
crayon: 1,
pencil: 1
}
}

更详细地说,每个键旁边的值是该关系的权重,也就是说,这些项目配对在一起的次数。我希望发生的事情是这样的:

// 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\' 对存储无效。' })。

我能做些什么来尽可能减少查询次数吗?我乐于接受建议。

编辑

我试图创建对象以传递到 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 不是一个独立的实体,sharpie 是一个项目。 1 个项目与其他项目之间的关系是 1 个项目有很多项目(1:M 递归),每个项目配对都有一个权重。

完全规范化后,您将拥有一个项目表和一个权重表。项目表将包含项目。权重表将具有类似 item1item2weight 的内容(在这样做时,您可以具有不对称权重,例如 sharpie: pencil = 1pencil:sharpie = .5,这在计算 FFA 中的推回时很有用,但我认为这不适用于您的情况。

太好了,现在让我们将其 mongotize。

当我们说 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。

关于javascript - Meteor 1.0 - 使用变量作为键的 Mongo 查询,包括 $inc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30953267/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com