如何使用 MongoDB 的 graphLookup 查询来回答问题:给我所有通过酒店连接到“X”的人
How to use graphLookup query of MongoDB to answer the question : Give me all persons connected to “X” through hotels
我的文档如下所示:
{ _id: 1, personId: 'Sai', pnr: "P1", flight: 'F1', hotel: 'H1' },
{ _id: 2, personId: 'Sai', pnr: "P2", flight: 'F2', hotel: 'H2' },
{ _id: 3, personId: 'Sai', pnr: "P3", flight: 'F3', hotel: 'H3' },
{ _id: 4, personId: 'Sai', pnr: "P4", flight: 'F4', hotel: 'H4' },
{ _id: 5, personId: 'Sai', pnr: "P5", flight: 'F5', hotel: 'H5' },
{ _id: 6, personId: 'PJ', pnr: "P1", flight: 'F1', hotel: 'H2' },
{ _id: 7, personId: 'PJ', pnr: "P2", flight: 'F1', hotel: 'H3' },
{ _id: 8, personId: 'Kumar', pnr: "P6", flight: 'F6', hotel: 'H1' },
{ _id: 9, personId: 'Kumar', pnr: "P7", flight: 'F7', hotel: 'H1' },
{ _id: 10, personId: 'Kumar', pnr: "P8", flight: 'F8', hotel: 'H1' },
{ _id: 11, personId: 'Kumar', pnr: "P9", flight: 'F9', hotel: 'H1' },
{ _id: 12, personId: 'Kannan', pnr: "P10", flight: 'F10', hotel: 'H1' },
{ _id: 13, personId: 'Kannan', pnr: "P11", flight: 'F11', hotel: 'H6' },
{ _id: 14, personId: 'Akansha', pnr: "P12", flight: 'F12', hotel: 'H6' },
{ _id: 15, personId: 'Akansha', pnr: "P13", flight: 'F13', hotel: 'H7' }
我想建立以下关系:
Sai(H1) --> Kannan(H1, H6) --> Akansha(H6)
我查询的输入应该仅为 'Sai' 和 'H1'。 graphLookup 应该完成所有其余工作以找到上述关系。谁能帮我做同样的事情。
我尝试了一些情况,但在所有这些情况下,我都必须在第一个 graphLookup 之后提供另一个输入才能找到确切的关系。我不希望出现这种情况,因为在现实世界中,我不知道任何文档之间的关系。
我试过的查询如下:
db.person_events.aggregate([
{ $match: { personId: 'Sai', hotel: 'H1' } },
{
$graphLookup: {
from: 'person_events',
startWith: '$hotel',
connectFromField: 'hotel',
connectToField: 'hotel',
as: 'hotel_connections'
}
},
{
$project: {
hotel_connections: 1, _id: 0
}
},
{
$project: {
hotel_connections: {
$filter: {
input: '$hotel_connections',
as: 'hotelConnection',
cond: { $eq: [ '$$hotelConnection.personId', 'Kannan' ] }
}
}
}
},
{
$graphLookup: {
from: 'person_events',
startWith: 'Kannan',
connectFromField: 'personId',
connectToField: 'personId',
as: 'person_connections'
}
},
{
$project: {
hotel_connections: 1, person_connections: 1, _id: 0
}
},
{
$graphLookup: {
from: 'person_events',
startWith: 'H6',
connectFromField: 'hotel',
connectToField: 'hotel',
as: 'final_connections'
}
}
])
我不认为你可以只使用 $graphlookup 得到你想要的输出,因为它会匹配它找到 H1 的任何地方并且因为你没有指定 maxDepth,它只会获取所有子文档但可以你在聚合管道中尝试这个,我不知道它是否有效,只是一个查询,我在查看你想要的酒店关系要求后开始工作,用你需要的查询输入替换 "Sai" 和 "H1" :
db.person_events.aggregate([
{
$group: {
_id: "$personId",
personId: {
$min: "$personId"
},
hotels: {
$push: "$hotel"
}
}
},
{
$match: {
personId: {
$ne: "Sai"
}
}
},
{
$lookup: {
from: "person_events",
let: {
personId: "$personId",
hotel: "$hotels"
},
as: "hotel_connections",
pipeline: [
{
$match: {
$expr: {
$and: [
{
$in: [
"$hotel",
"$$hotel"
]
},
{
$ne: [
"H1",
"$hotel"
]
},
{
$ne: [
"$personId",
"$$personId"
]
},
{
$ne: [
"Sai",
"$personId"
]
}
],
}
}
},
{
$group: {
_id: "$personId",
hotel: {
$min: "$hotel"
},
personId: {
$min: "$personId"
}
}
}
]
}
},
{
$match: {
hotels: {
$in: [
"H1"
]
},
hotel_connections: {
$ne: []
}
}
}
])
我的文档如下所示:
{ _id: 1, personId: 'Sai', pnr: "P1", flight: 'F1', hotel: 'H1' },
{ _id: 2, personId: 'Sai', pnr: "P2", flight: 'F2', hotel: 'H2' },
{ _id: 3, personId: 'Sai', pnr: "P3", flight: 'F3', hotel: 'H3' },
{ _id: 4, personId: 'Sai', pnr: "P4", flight: 'F4', hotel: 'H4' },
{ _id: 5, personId: 'Sai', pnr: "P5", flight: 'F5', hotel: 'H5' },
{ _id: 6, personId: 'PJ', pnr: "P1", flight: 'F1', hotel: 'H2' },
{ _id: 7, personId: 'PJ', pnr: "P2", flight: 'F1', hotel: 'H3' },
{ _id: 8, personId: 'Kumar', pnr: "P6", flight: 'F6', hotel: 'H1' },
{ _id: 9, personId: 'Kumar', pnr: "P7", flight: 'F7', hotel: 'H1' },
{ _id: 10, personId: 'Kumar', pnr: "P8", flight: 'F8', hotel: 'H1' },
{ _id: 11, personId: 'Kumar', pnr: "P9", flight: 'F9', hotel: 'H1' },
{ _id: 12, personId: 'Kannan', pnr: "P10", flight: 'F10', hotel: 'H1' },
{ _id: 13, personId: 'Kannan', pnr: "P11", flight: 'F11', hotel: 'H6' },
{ _id: 14, personId: 'Akansha', pnr: "P12", flight: 'F12', hotel: 'H6' },
{ _id: 15, personId: 'Akansha', pnr: "P13", flight: 'F13', hotel: 'H7' }
我想建立以下关系:
Sai(H1) --> Kannan(H1, H6) --> Akansha(H6)
我查询的输入应该仅为 'Sai' 和 'H1'。 graphLookup 应该完成所有其余工作以找到上述关系。谁能帮我做同样的事情。
我尝试了一些情况,但在所有这些情况下,我都必须在第一个 graphLookup 之后提供另一个输入才能找到确切的关系。我不希望出现这种情况,因为在现实世界中,我不知道任何文档之间的关系。
我试过的查询如下:
db.person_events.aggregate([
{ $match: { personId: 'Sai', hotel: 'H1' } },
{
$graphLookup: {
from: 'person_events',
startWith: '$hotel',
connectFromField: 'hotel',
connectToField: 'hotel',
as: 'hotel_connections'
}
},
{
$project: {
hotel_connections: 1, _id: 0
}
},
{
$project: {
hotel_connections: {
$filter: {
input: '$hotel_connections',
as: 'hotelConnection',
cond: { $eq: [ '$$hotelConnection.personId', 'Kannan' ] }
}
}
}
},
{
$graphLookup: {
from: 'person_events',
startWith: 'Kannan',
connectFromField: 'personId',
connectToField: 'personId',
as: 'person_connections'
}
},
{
$project: {
hotel_connections: 1, person_connections: 1, _id: 0
}
},
{
$graphLookup: {
from: 'person_events',
startWith: 'H6',
connectFromField: 'hotel',
connectToField: 'hotel',
as: 'final_connections'
}
}
])
我不认为你可以只使用 $graphlookup 得到你想要的输出,因为它会匹配它找到 H1 的任何地方并且因为你没有指定 maxDepth,它只会获取所有子文档但可以你在聚合管道中尝试这个,我不知道它是否有效,只是一个查询,我在查看你想要的酒店关系要求后开始工作,用你需要的查询输入替换 "Sai" 和 "H1" :
db.person_events.aggregate([
{
$group: {
_id: "$personId",
personId: {
$min: "$personId"
},
hotels: {
$push: "$hotel"
}
}
},
{
$match: {
personId: {
$ne: "Sai"
}
}
},
{
$lookup: {
from: "person_events",
let: {
personId: "$personId",
hotel: "$hotels"
},
as: "hotel_connections",
pipeline: [
{
$match: {
$expr: {
$and: [
{
$in: [
"$hotel",
"$$hotel"
]
},
{
$ne: [
"H1",
"$hotel"
]
},
{
$ne: [
"$personId",
"$$personId"
]
},
{
$ne: [
"Sai",
"$personId"
]
}
],
}
}
},
{
$group: {
_id: "$personId",
hotel: {
$min: "$hotel"
},
personId: {
$min: "$personId"
}
}
}
]
}
},
{
$match: {
hotels: {
$in: [
"H1"
]
},
hotel_connections: {
$ne: []
}
}
}
])