我是MongoDb的新手,我正在尝试查看是否可以在Mongodb中执行exists()查询。
我玩的收藏品包含用户(包括公司和计费组等详细信息)和期望公司。
通常在Oracle中,用户和expectedCompanies将在两个表中,我会这样查询:
SELECT *
FROM tableUsers
WHERE exists (
SELECT 1
FROM tableExpectedCompanies
WHERE
tableExpectedCompanies.companyname != tableUsers.companyName and
tableExpectedCompanies.billingGroup = tableUsers.companyName.billingGroup
)
在MongoDb中,它现在都在一个集合中,大致如下:
{
"_id" : "billingGroupX",
"expectedCompanies" : ["CompanyA", "company B", "supercompany X"],
"users" : [{"name":..., "company": ...}, {}, {}]
}
我希望我能做到这样的事情:
db.MasterData.find(
{'users.company':
{$nin: db.MasterData.find(
{},
{'expectedCompanies:1'})
}
})
但当然失败了,第一个错误是:
error: { "$err" : "$nin needs an array", "code" : 13277 }
MongoDb中是否存在实际存在或不存在的类似物?
或
修改:对我的问题做出初步的负面反馈。请注意,我很难找到存在/不存在/处于/不处于条件的情况,您可以使用子查询,因为它通常在SQL中完成。
答案 0 :(得分:5)
好的,这是您需要了解的声明。
MongoDB不做联接
即使在此子查询表单中,您也不能在您的语句中包含来自其他集合的其他查询。也就是说,请注意以下几点:
错误:{“$ err”:“$ nin需要一个数组”,“代码”:13277}
所以你没有按要求提供数组,但你试图提出一个声明。然后你可以考虑代码:
var results = db.MasterData.find({}, {"expectedCompanies:1"}).toArray();
单独查看它会看到它将从所有结果中返回“expectedCompanies”字段。我在最后添加.toArray()
功能,以表明您可能尝试做的事情无法正常工作,因为您将获得光标,不是一个数组。但是这在这里不起作用,因为数组甚至从这个语句引用整个集合,而不仅仅是来自一个文档。
因此,您可能正在“尝试”做的是将“users.company”值与“expectedCompanies”值匹配(或明确地 匹配)。所以在MongoDB中你可以这样做:
db.MasterData.aggregate([
// Unwind the "users" array
{ "$unwind": "$users" },
// Unwind the "expectedCompanies" array
{ "$unwind": "$expectedCompanies" },
// Project a match condition
{ "$project": {
"users": 1,
"matching": { "$eq": [
"$users.company",
"$expectedCompanies"
]}
}},
// Filter the results
{ "$match": { "matching": false }},
// Group the duplicate entries from the unwind
{ "$group": {
"_id": {
"_id": "$_id",
"users": {
"name": "$users.name",
"company": "$users.company"
}
}
}},
// Project a nicer document
{ "$project": {
"_id": "$_id._id",
"users": "$_id.users"
}}
])
这使用aggregate来$unwind数组中的元素,并将它们相互比较。每个阵列需要在不同的阶段“解开”。实际比较在第一个$project阶段完成,使用$eq逻辑运算符来比较这两个值。如果它们相等,则结果为true
,而不是false
。
然后,我们使用$ match阶段将结果“过滤”为我们想要的false
值。这就像普通的.find()
查询一样。然后通过$group发送结果,将“用户”文档中的密钥汇集在一起。这是因为当阵列“未缠绕”时,每个条目被“复制”为另一个“expectedCompanies”数组中的每个元素。可以想象$unwind形式就像“去标准化”数据一样。分组在此处删除重复项。
最后,由于所有内容都在一个键下“分组”,然后再次使用$project将结果重新塑造成更符合您想要的内容。
因此,使用情况与“子查询”形式有点不同,但这就是你如何使用比较两个数组中的值的语句。你的文件。
答案 1 :(得分:-1)
以下是用于Exist()或IN()SQL函数转换的不同方法。 这是一个简单的javascript实用程序,但是为了提高性能,您将需要适当的索引。
var mycursor = db.tableUsers.find( {} )
mycursor.forEach( function (x){
var o = db.tableExpectedCompanies.count( { billingGroup : x.billingGroup, companyname : {$ne: x.companyName} } )
if ( o > 0) {
//print('The _id exists! ' + x._id); //debugging only
printjson(x) ;
}
} )