完全匹配的子文档很容易,但有没有一种方法可以精确地匹配集合中的整个文档?如何精确匹配整个文档?
我有很多类似的数据文件,而我只需要准确的,没有额外的数据
使用负$存在将不适合我,因为我不知道所有事先可能的领域相匹配。
完全匹配的子文档很容易,但有没有一种方法可以精确地匹配集合中的整个文档?如何精确匹配整个文档?
我有很多类似的数据文件,而我只需要准确的,没有额外的数据
使用负$存在将不适合我,因为我不知道所有事先可能的领域相匹配。
我不认为这是可能的顾左右而言他,但可能的解决方案是散列文件。
保存时,总是创建文件的哈希:
var doc = {};
delete doc.hash; // never include the hash itself in the calculation
doc.hash = crypto.createHash('sha256').update(JSON.stringify(doc)).digest();
db.collection.insert(doc);
然后查询时,您可以通过哈希查询:
db.collection.find({
hash: hash
})
可能是讨厌的,如果你经常做的原子更新文件。
这种吸引力,特别是因为你可以完全匹配子文档 – Dracony
一个优雅的解决方案,应该不存在的问题。谢谢! –
我真的不明白你的问题,你能解释一下吗?
如果你想要的文件没有一些字段,你可以使用$存在。
举例来说,如果你有...
{a: 1 , b: "1", c: true }
{a: 2, b: "2", c: false}
{a: null, b: "3" }
然后db.my_collection.find({a: {$exists: true}});
发现
{a: 1 , b: "1", c: true }
{a: 2, b: "2", c: false}
而且db.my_collection.find({a: {$exists: false}});
发现
{a: null, b: "3" }
这样的文档,我不能依赖$ exists,因为有太多可能领域。 – Dracony
不是一个理想的方法,但真正的唯一方法是在服务器上过滤掉这个问题,就是使用JavaScript评估运算符。确保它与传统查询一起使用,尽管至少从索引选择中获得了一些性能优势,因为JavaScript本身无法做到这一点。
考虑以下几点:
{ "a" : 1 }
{ "a" : 1, "b" : 2 }
{ "a" : 1, "b" : 2, "c" : 3 }
{ "a" : 1, "b" : 2, "c" : 3, "d" : 4 }
所以,现在你需要“第三”的文件只匹配。这里的基本代码的概念:
var query = { "a": 1, "b": 2, "c": 3 };
var string = "";
Object.keys(query).forEach(function(key) {
if (query[key].constructor.toString().match(/(Array|Object)/) == null)
string += key + query[key].valueOf().toString();
});
query['$where'] = 'function() { ' +
'var compare = ""; ' +
'var string = "' + string + '"; ' +
'var doc = this; ' +
'delete doc._id; ' +
'Object.keys(doc).forEach(function(key) { ' +
'if (doc[key].contructor.toString().match(/(Array|Object)/) == null) ||' +
'compare += key + doc[key].valueOf().toString(); ' +
'}); ' +
'return compare == string; ' +
'};';
db.test.find(query);
有些司机有更好的概念混用的外部变量转换成代码,但它给出了基本思路。
您需要根据所需的确切字段和值计算外部图片或哈希值,然后在服务器上使用相同的方法来计算当前文档字段中的值。自然地,_id
总是被排除,因为它是唯一的。
你不需要子元素的签名,因为正如你所说的,你可以完全匹配那些纯粹在查询中的元素。所以这只是一个排除比较一代的问题。
通用查询参数将完成大部分工作,在这种情况下,可将其缩小到两个文档,理想情况下使用索引来完成。剩余的匹配是通过“强力”JavaScript评估完成的,因此只有与查询中的字段具有匹配签名的文档。
你究竟是什么意思的“完全匹配”的子文件?如果不知道那里所有可能的领域,你如何看待你?这听起来像混淆了我很不清楚。 –
好,如果我正在查找文档{a:5}我不希望它匹配{a:5,b:1},只有{a:5} – Dracony
您误解了我的示例。我说,如果我查询{a:1},我只需要文档是{a:1}而不是像{a:1,b:1} – Dracony