如何使用 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: []
      }
    }
  }
])