使用 mongo 添加两个额外的过滤器 1 collection
Add two extra filter of 1 collection using mongo
我有 4 个 collections:
用户
users: { id: '123123123', name: 'MrMins' }
匹配
{ id: 1, team1: 23, team2: 24, date: '6/14', matchday: 1, locked: false, score1: null, score2: null }
{ id: 2, team1: 9, team2: 32, date: '6/15', matchday: 1, locked: false, score1: null, score2: null }
国家
{id: 23, country: "Russia", pais: "Rusia", group: 'A' }
{id: 24, country: "Saudi Arabia", pais: "Arabia Saudita", group: 'A' }
{id: 9, country: "Egypt", pais: "Egipto", group: 'A' }
{id: 32, country: "Uruguay", pais: "Uruguay", group: 'A' }
预测
{ matchid: 1, score1: 3, score2: 4, userid: '123123123' }
{ matchid: 2, score1: 3, score2: 0, userid: '123123123' }
我的查询:
db.collection('matches').aggregate([
{
$lookup: {
from: 'countries',
localField: 'team1',
foreignField: 'id',
as: 'team1'
}
},{
$lookup: {
from: 'countries',
localField: 'team2',
foreignField: 'id',
as: 'team2'
}
}
]).toArray(function(err, res) {
callback(err, res);
});
刚才,我有matches
和countries
(两次)之间的关系。
如何将附加过滤器添加到 forecast
与 matchid
和 userid
建立关系?
$lookup
用作左外连接,但它会将 "joined" 结果作为数组插入文档中。因此,您添加的每个字段(使用 as
选项)都将是一个数组。
要从 forecasts
和 users
获取数据,您必须将该数组转换为一个对象,您可以使用 $arrayElemAt 运算符:
db.matches.aggregate([
{
$lookup: {
from: 'countries',
localField: 'team1',
foreignField: 'id',
as: 'team1'
}
},{
$lookup: {
from: 'countries',
localField: 'team2',
foreignField: 'id',
as: 'team2'
}
},{
$lookup: {
from: 'forecast',
localField: 'id',
foreignField: 'matchid',
as: 'forecast'
}
}, {
$addFields: {
forecast: { $arrayElemAt: [ "$forecast", 0 ] }
}
},{
$lookup: {
from: 'users',
localField: 'forecast.userid',
foreignField: 'id',
as: 'forecast.user'
}
}
])
使用嵌套管道 mongodb 3.6 $lookup
版本会非常简单
db.matches.aggregate([
{
$lookup: {
from: 'countries',
let: { 'team1': '$team1' },
pipeline: [
{ $match: { $expr: { $eq: [ '$id', '$$team1' ] } }}
],
as: 'team1'
}
},{
$lookup: {
from: 'countries',
let: { 'team2': '$team2' },
pipeline: [
{ $match: { $expr: { $eq: [ '$id', '$$team2' ] } }}
],
as: 'team2'
}
}, {
$lookup: {
from: 'forecast',
let: { "match_id": "$id" },
pipeline: [
{ $match: { $expr: { $eq: [ '$matchid', '$$match_id' ] } }},
{ $lookup: {
from: 'users',
let: { 'userid': '$userid' },
pipeline: [
{ $match: { $expr: { $eq: [ '$id', '$$userid' ] } }}
],
as: 'user'
}}
],
as: 'forecast'
}
}
])
我有 4 个 collections:
用户
users: { id: '123123123', name: 'MrMins' }
匹配
{ id: 1, team1: 23, team2: 24, date: '6/14', matchday: 1, locked: false, score1: null, score2: null }
{ id: 2, team1: 9, team2: 32, date: '6/15', matchday: 1, locked: false, score1: null, score2: null }
国家
{id: 23, country: "Russia", pais: "Rusia", group: 'A' }
{id: 24, country: "Saudi Arabia", pais: "Arabia Saudita", group: 'A' }
{id: 9, country: "Egypt", pais: "Egipto", group: 'A' }
{id: 32, country: "Uruguay", pais: "Uruguay", group: 'A' }
预测
{ matchid: 1, score1: 3, score2: 4, userid: '123123123' }
{ matchid: 2, score1: 3, score2: 0, userid: '123123123' }
我的查询:
db.collection('matches').aggregate([
{
$lookup: {
from: 'countries',
localField: 'team1',
foreignField: 'id',
as: 'team1'
}
},{
$lookup: {
from: 'countries',
localField: 'team2',
foreignField: 'id',
as: 'team2'
}
}
]).toArray(function(err, res) {
callback(err, res);
});
刚才,我有matches
和countries
(两次)之间的关系。
如何将附加过滤器添加到 forecast
与 matchid
和 userid
建立关系?
$lookup
用作左外连接,但它会将 "joined" 结果作为数组插入文档中。因此,您添加的每个字段(使用 as
选项)都将是一个数组。
要从 forecasts
和 users
获取数据,您必须将该数组转换为一个对象,您可以使用 $arrayElemAt 运算符:
db.matches.aggregate([
{
$lookup: {
from: 'countries',
localField: 'team1',
foreignField: 'id',
as: 'team1'
}
},{
$lookup: {
from: 'countries',
localField: 'team2',
foreignField: 'id',
as: 'team2'
}
},{
$lookup: {
from: 'forecast',
localField: 'id',
foreignField: 'matchid',
as: 'forecast'
}
}, {
$addFields: {
forecast: { $arrayElemAt: [ "$forecast", 0 ] }
}
},{
$lookup: {
from: 'users',
localField: 'forecast.userid',
foreignField: 'id',
as: 'forecast.user'
}
}
])
使用嵌套管道 mongodb 3.6 $lookup
版本会非常简单
db.matches.aggregate([
{
$lookup: {
from: 'countries',
let: { 'team1': '$team1' },
pipeline: [
{ $match: { $expr: { $eq: [ '$id', '$$team1' ] } }}
],
as: 'team1'
}
},{
$lookup: {
from: 'countries',
let: { 'team2': '$team2' },
pipeline: [
{ $match: { $expr: { $eq: [ '$id', '$$team2' ] } }}
],
as: 'team2'
}
}, {
$lookup: {
from: 'forecast',
let: { "match_id": "$id" },
pipeline: [
{ $match: { $expr: { $eq: [ '$matchid', '$$match_id' ] } }},
{ $lookup: {
from: 'users',
let: { 'userid': '$userid' },
pipeline: [
{ $match: { $expr: { $eq: [ '$id', '$$userid' ] } }}
],
as: 'user'
}}
],
as: 'forecast'
}
}
])