提问人:John Saunders 提问时间:5/23/2015 最后编辑:CommunityJohn Saunders 更新时间:5/23/2015 访问量:586
如何找到与断开的“外键”关系等价物?
How to Find the Equivalent of Broken "Foreign Key" Relationships?
问:
我有两个集合,如果这是一个关系数据库,它们就属于我们所说的“一对一关系”。我不知道为什么一个没有嵌套在另一个文档中,但事实是,对于集合“A”中的每个文档,集合“B”中都应该有一个文档,反之亦然。
当然,在没有外键约束的情况下,在存在错误的情况下,有时“A”中的文档在“B”中没有相关文档(反之亦然)。
我是MongoDB的新手,我在创建查询或脚本时遇到了问题,该查询或脚本将找到“A”中的所有文档,而这些文档在“B”中没有相关文档(反之亦然)。我想我可以使用某种循环,但我还不知道它是如何工作的——我才刚刚开始在 RoboMongo 命令行上使用简单的查询。
谁能让我开始为此编写脚本?我看过“验证MongoDB中的引用(外键)完整性”,但这对我没有帮助。一个错误导致“引用完整性”崩溃,我需要脚本来帮助我跟踪错误。我也无法重新设计数据库以使用嵌入(尽管我希望我会问为什么一个文档没有嵌套在另一个文档中)。
我还看到了“如何使用 MongoDB 在集合中查找不在另一个集合中的项目”,但它没有答案。
不良技术的伪代码
var misMatches = [];
var collectionB = db.getCollection('B');
var allOfA = db.getCollection('A').find();
while (allOfA.hasNext()) {
var nextA = allOfA.next();
if (!collectionB.find(nextA._id)) {
misMatches.push(nextA._id);
}
}
答:
3赞
Sylvain Leroux
5/23/2015
#1
我不知道这是否能很好地扩展,但是......
...给定此示例日期集:
> db.a.insert([{a:1},{a:2},{a:10} ])
> db.b.insert([ {b:2},{b:10},{b:20}])
// ^^^^^ ^^^^^^
// inconsistent 1-to-1 relationship
你可以使用 map-reduce 来收集 key 集,并将其与 from 中的 key 集合并:a
b
mapA=function() {
emit(this.a, {col: ["a"]})
}
mapB=function() {
emit(this.b, {col: ["b"]})
}
reduce=function(key, values) {
// merge both `col` arrays; sort the result
return {col: values.reduce(
function(a,b) { return a.col.concat(b.col) }
).sort()}
}
生产:
> db.a.mapReduce(mapA, reduce, {out:{replace:"result"}})
> db.b.mapReduce(mapB, reduce, {out:{reduce:"result"}})
> db.result.find()
{ "_id" : 1, "value" : { "col" : [ "a" ] } }
{ "_id" : 2, "value" : { "col" : [ "a", "b" ] } }
{ "_id" : 10, "value" : { "col" : [ "a", "b" ] } }
{ "_id" : 20, "value" : { "col" : [ "b" ] } }
然后很容易找到所有在集合中找不到的 id,并且 .此外,您应该能够在一个或另一个集合中发现重复的键:a
b
> db.result.find({"value.col": { $ne: [ "a", "b" ]}})
{ "_id" : 1, "value" : { "col" : [ "a" ] } }
{ "_id" : 20, "value" : { "col" : [ "b" ] }
评论
_id
collection.findOne() != null
告诉您已找到结果或反之不匹配。像返回游标这样的方法,因此检查是不合逻辑的。.find()