无法推断查询字段以在插入时设置错误
Cannot infer query fields to set error on insert
我正在尝试使用 "findAndModify" 实现 "getOrCreate" 行为。
我正在使用本机驱动程序在 nodejs 中工作。
我有:
var matches = db.collection("matches");
matches.findAndModify({
//query
users: {
$all: [ userA_id, userB_id ]
},
lang: lang,
category_id: category_id
},
[[ "_id", "asc"]], //order
{
$setOnInsert: {
users: [userA_id, userB_id],
category_id: category_id,
lang: lang,
status: 0
}
},
{
new:true,
upsert:true
}, function(err, doc){
//Do something with doc
});
我想做的是:
"Find specific match with specified users, lang and category... if not found, insert a new one with specified data"
Mongo 抛出此错误:
Error getting/creating match { [MongoError: exception: cannot infer query fields to set, path 'users' is matched twice]
name: 'MongoError',
message: 'exception: cannot infer query fields to set, path \'users\' is matched twice',
errmsg: 'exception: cannot infer query fields to set, path \'users\' is matched twice',
code: 54,
ok: 0 }
有没有办法让它工作?
不可能?
谢谢:)
这不是处理此问题的 "prettiest" 方法,但当前对选择运算符的限制意味着您需要使用带有 $where
.
的 JavaScript 表达式
为便于示例,用您的变量替换值:
matches.findAndModify(
{
"$where": function() {
var match = [1,2];
return this.users.filter(function(el) {
return match.indexOf(el) != -1;
}).length >= 2;
},
"lang": "en",
"category_id": 1
},
[],
{
"$setOnInsert": {
"users": [1,2],
"lang": "en",
"category_id": 1
}
},
{
"new": true,
"upsert": true
},
function(err,doc) {
// do something useful here
}
);
您可能会怀疑,这里的 "culprit" 是 positional $
operator,即使您的操作没有使用它。
这个问题具体是因为 $all
正在寻找数组中 "two" 位置的可能匹配项。如果需要 "positional" 运算符,引擎无法计算出(目前)显示哪个位置。该位置可以说是 "first" 与其他操作一致的匹配,但它目前不是这样工作的。
用 JavaScript 表达式替换逻辑可以避免这种情况,因为 JavaScript 逻辑无论如何都不能 return 匹配的位置。这使得表达式有效,然后您可以 "create" 和新文档中包含这两个元素的数组,或者检索包含 "both" 这些元素以及其他查询条件的文档。
P.S有点担心你的"sort"。您可能已经添加了它,因为它是 "mandatory" 到方法中,但是如果您确实希望它与 "more than one" 文档匹配并且需要 "sort" 来确定要获取哪个,那么您的逻辑是有点瑕疵。
当对 "find or create" 执行此操作时,您确实 需要 在查询中指定 "all" 的 "unique" 键约束。如果你不这样做,那么你很可能 运行 进入重复键错误。
如果您实际上不需要 "pick" 来自多个的结果,那么排序实际上可以是一个空数组。
只是要记住一些事情。
我正在尝试使用 "findAndModify" 实现 "getOrCreate" 行为。 我正在使用本机驱动程序在 nodejs 中工作。
我有:
var matches = db.collection("matches");
matches.findAndModify({
//query
users: {
$all: [ userA_id, userB_id ]
},
lang: lang,
category_id: category_id
},
[[ "_id", "asc"]], //order
{
$setOnInsert: {
users: [userA_id, userB_id],
category_id: category_id,
lang: lang,
status: 0
}
},
{
new:true,
upsert:true
}, function(err, doc){
//Do something with doc
});
我想做的是: "Find specific match with specified users, lang and category... if not found, insert a new one with specified data"
Mongo 抛出此错误:
Error getting/creating match { [MongoError: exception: cannot infer query fields to set, path 'users' is matched twice]
name: 'MongoError',
message: 'exception: cannot infer query fields to set, path \'users\' is matched twice',
errmsg: 'exception: cannot infer query fields to set, path \'users\' is matched twice',
code: 54,
ok: 0 }
有没有办法让它工作? 不可能?
谢谢:)
这不是处理此问题的 "prettiest" 方法,但当前对选择运算符的限制意味着您需要使用带有 $where
.
为便于示例,用您的变量替换值:
matches.findAndModify(
{
"$where": function() {
var match = [1,2];
return this.users.filter(function(el) {
return match.indexOf(el) != -1;
}).length >= 2;
},
"lang": "en",
"category_id": 1
},
[],
{
"$setOnInsert": {
"users": [1,2],
"lang": "en",
"category_id": 1
}
},
{
"new": true,
"upsert": true
},
function(err,doc) {
// do something useful here
}
);
您可能会怀疑,这里的 "culprit" 是 positional $
operator,即使您的操作没有使用它。
这个问题具体是因为 $all
正在寻找数组中 "two" 位置的可能匹配项。如果需要 "positional" 运算符,引擎无法计算出(目前)显示哪个位置。该位置可以说是 "first" 与其他操作一致的匹配,但它目前不是这样工作的。
用 JavaScript 表达式替换逻辑可以避免这种情况,因为 JavaScript 逻辑无论如何都不能 return 匹配的位置。这使得表达式有效,然后您可以 "create" 和新文档中包含这两个元素的数组,或者检索包含 "both" 这些元素以及其他查询条件的文档。
P.S有点担心你的"sort"。您可能已经添加了它,因为它是 "mandatory" 到方法中,但是如果您确实希望它与 "more than one" 文档匹配并且需要 "sort" 来确定要获取哪个,那么您的逻辑是有点瑕疵。
当对 "find or create" 执行此操作时,您确实 需要 在查询中指定 "all" 的 "unique" 键约束。如果你不这样做,那么你很可能 运行 进入重复键错误。
如果您实际上不需要 "pick" 来自多个的结果,那么排序实际上可以是一个空数组。
只是要记住一些事情。