mongodb $lookup 结果中的 $match
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42091088/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
$match in $lookup result
提问by AlexBerd
I have next mongo code:
我有下一个 mongo 代码:
db.users.aggregate([
{
$match: {
$and: [
{ UserName: { $eq: 'administrator' } },
{ 'Company.CompanyName': { $eq: 'test' } }
]
}
},
{
$lookup: {
from: "companies",
localField: "CompanyID",
foreignField: "CompanyID",
as: "Company"
}
},
])
The $lookup
part of the code working great. I got next result:
$lookup
代码的一部分工作得很好。我得到了下一个结果:
But if I add $match
to the code, it brings nothing.
但是如果我添加$match
到代码中,它不会带来任何东西。
I found that the problem is in the second match: { 'Company.CompanyName': { $eq: 'test' } }
, but I can not realize what is wrong with it.
Any ideas?
我发现问题出在第二场比赛中: { 'Company.CompanyName': { $eq: 'test' } }
,但我无法意识到它有什么问题。有任何想法吗?
UPDATE:
更新:
I had also tried $unwind
on the $lookup
result, but no luck:
我还曾试图$unwind
对$lookup
结果,但没有运气:
db.users.aggregate([
{
$match: {
$and: [
{ UserName: { $eq: 'administrator' } },
{ 'Company.CompanyName': { $eq: 'edt5' } }
]
}
},
{ unwind: '$Company' },
{
$lookup: {
from: 'companies',
localField: 'CompanyID',
foreignField: 'CompanyID',
as: 'Company'
}
},
])
回答by chridam
With MongoDB 3.4, you can run an aggregation pipeline that uses the $addFields
pipeline and a $filter
operator to only return the Company
array with elements that match the given condition. You can then wrap the $filter
expression with the $arrayElemAt
operator to return a single document which in essence incorporates the $unwind
functionality by flattening the array.
使用 MongoDB 3.4,您可以运行聚合管道,该$addFields
管道使用管道和$filter
运算符仅返回Company
具有与给定条件匹配的元素的数组。然后,您可以$filter
使用$arrayElemAt
运算符包装表达式以返回单个文档,该文档实质上$unwind
通过展平数组来合并功能。
Follow this example to understand the above concept:
按照这个例子来理解上面的概念:
db.users.aggregate([
{ "$match": { "UserName": "administrator" } },
{
"$lookup": {
"from": 'companies',
"localField": 'CompanyID',
"foreignField": 'CompanyID',
"as": 'Company'
}
},
{
"$addFields": {
"Company": {
"$arrayElemAt": [
{
"$filter": {
"input": "$Company",
"as": "comp",
"cond": {
"$eq": [ "$$comp.CompanyName", "edt5" ]
}
}
}, 0
]
}
}
}
])
回答by Jan Franciszek Cie?lak
Below answer is for mongoDB 3.6 or later.
以下答案适用于 mongoDB 3.6 或更高版本。
Given that:
鉴于:
- You have a collection
users
with a fieldCompanyID
and a collection ofcompanies
with a fieldCompanyID
you want to lookup
Companies
onUsers
by matchingCompanyID
, where additionally:- each User must match condition:
User.UserName
equalsadministrator
- each
Company
onUser
must match condition:CompanyName
equalsedt5
- each User must match condition:
- 你有收集
users
与现场CompanyID
和集合companies
与现场CompanyID
要查找
Companies
有关Users
的匹配CompanyID
,其中另外:- 每个用户必须匹配条件:
User.UserName
等于administrator
- 每个
Company
上User
必须符合的条件:CompanyName
平等edt5
- 每个用户必须匹配条件:
The following query will work for you:
以下查询对您有用:
db.users.aggregate([
{ $match: { UserName: 'administrator' } },
{
$lookup: {
from: 'companies',
as: 'Company',
let: { CompanyID: '$CompanyID' },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ['$CompanyID', '$$CompanyID'] },
{ $eq: ['$CompanyName', 'edt5'] },
]
}
}
}
]
}
},
])
Explanation:This is the way to perform left join queries with conditions more complex than simple foreign / local field equality match.
说明:这是在条件比简单的外部/本地字段相等匹配更复杂的情况下执行左连接查询的方法。
Instead of using localField
and foreignField
, you use:
而不是使用localField
and foreignField
,你使用:
let
option where you can map local fields to variables,pipeline
option where you can specify aggregationArray
.
let
您可以将本地字段映射到变量的选项,pipeline
您可以在其中指定聚合的选项Array
。
In pipeline
you can use $match
filter, with $expr
, where you can reuse variables defined earlier in let
.
在pipeline
你可以使用$match
过滤器,带$expr
,在那里你可以重复使用先前在定义的变量let
。