【问题标题】:Linking collections in GraphQL resolver在 GraphQL 解析器中链接集合
【发布时间】:2021-02-02 01:07:32
【问题描述】:

我正在尝试在 GraphQL 查询中加入两个集合。

我的数据如下: 游轮:

[
  {
    "cruiseID" : "00001",
    "title" : "title 1",
    "description" : "desc 1",
    "startDate" : 20150820,
    "endDate" : 20150827,
    "numDays" : 8,
    "startPort" : "Juneau, Alaska",
    "roomTypes" : [
      {"roomID" : "IPD"},
      {"roomID" : "SDS"}
    ]
  }, {
    "cruiseID" : "00002",
    "title" : "title 1",
    "description" : "desc 2",
    "startDate" : 20150710,
    "endDate" : 20150724,
    "numDays" : 14,
    "startPort" : "San Diego",
    "roomTypes" : [
      {"roomID" : "IPD"},
      {"roomID" : "SJS"},
      {"roomID" : "SDS"}
    ]
  }
]

房间:

[
  {
    "roomID": "IPD",
    "roomDetails": {
        "roomType": "IPD aaaaa",
        "title": "aaaa",
        "description": "ddddd",
        "maxOccupants": 2
    },
    "capacity": [
      {"cruiseID": "00001", "total": 21, "available": 20},
      {"cruiseID": "00002", "total": 31, "available": 30}
    ]
  },
  {
    "roomID": "SJS",
    "roomDetails": {
        "roomType": "SJS aaaa",
        "title": "aaaaa",
        "description": "aaaaa",
        "maxOccupants": 4
    },
    "capacity": [
      {"cruiseID": "00001", "available": 27},
      {"cruiseID": "00002", "available": 27}
    ]
  },
  {
    "roomID": "SDS",
    "roomDetails": {
        "roomType": "SDS aaa",
        "title": "sssss",
        "description": "sssssss",
        "maxOccupants": 4
    },
    "capacity": [
      {"cruiseID": "00001", "available": 20},
      {"cruiseID": "00002", "available": 20}
    ]
  }
]

我的 GraphQL 架构:

type Query {
  Cruises: [Cruise]
}

type RoomDetails {
  roomType: String
  title: String
  description: String
  maxOccupants: Int
}

type Capacity {
  cruiseID: String
  total: Int
  available: Int
}

type Room {
  roomID: String
  roomDetails: RoomDetails
  capacity: [Capacity]
}

type Cruise {
  _id: ID
  cruiseID: String
  title: String
  description: String
  startDate: Int
  endDate: Int
  numDays: Int
  startPort: String
  roomTypes: [Room]
}

我的 GraphQL 解析器,我尝试通过从房间集合中读取房间类型来打印房间类型的详细信息:

const Query = {
  Cruises: async () => {
    data = await db.collection('cruises').find().toArray().then(res => { return res });
    return data
  }
}

const Cruise = {
  roomTypes: async (root) => {
    data = await db.collection('rooms').find({'roomID': 'SDS'}).toArray().then(res => { return res });
    // prints OK
    logger.debug(`root.roomTypes.roomID': ${JSON.stringify(root.roomTypes[1].roomID)}`);
    // undefined
    logger.debug(`root.roomTypes.roomID': ${JSON.stringify(root.roomTypes.roomID)}`);
    // prints OK
    logger.debug(`root.startPort': ${root.startPort}`);
    return data
  }
}

module.exports = {
  Query,
  Cruise
}

我在 Cruises 和 Rooms 之间找不到合适的连接。 硬编码 {'roomID': 'SDS'} 工作正常,即显示正确的输出。 但是,我找不到正确将 Cruises 中的 roomID 传递给 find 过滤器的方法。有什么提示吗?

更新: 当我实现解析器生命时:

const Cruise = {
  roomTypes: async (root) => {
    data = await db.collection('rooms').find({'capacity.cruiseID': root.cruiseID}).toArray().then(res => { return res })
    //data = await db.collection('rooms').find().toArray().then(res => { return res })

    return data
  }
}

我取回了数据(roomTypes 完全解析),但它实际上并没有进行任何过滤/加入。 这是我得到的(用一些垃圾数据编辑,所以它更短):

    "data": {
        "Cruises": [
            {
                "cruiseID": "00001",
                "title": "and",
                "startDate": 20150820,
                "endDate": 20150827,
                "numDays": 8,
                "startPort": "Juneau, Alaska",
                "roomTypes": [
                    {
                        "roomID": "IPD",
                        "roomDetails": {
                            "roomType": "asd",
                            "title": "and",
                            "description": "asdr",
                            "maxOccupants": 2
                        },
                        "capacity": [
                            {
                                "cruiseID": "00001",
                                "total": 21,
                                "available": 20
                            },
                            {
                                "cruiseID": "00002",
                                "total": 31,
                                "available": 30
                            }
                        ]
                    },
                    {
                        "roomID": "OPD",
                        "roomDetails": {
                            "roomType": "ad",
                            "title": "and",
                            "description": "asdr",
                            "maxOccupants": 2
                        },
                        "capacity": [
                            {
                                "cruiseID": "00001",
                                "total": null,
                                "available": 30
                            },
                            {
                                "cruiseID": "00002",
                                "total": null,
                                "available": 30
                            }
                        ]
                    },
                    {
                        "roomID": "SDD",
                        "roomDetails": {
                            "roomType": "asd",
                            "title": "and",
                            "description": "and",
                            "maxOccupants": 2
                        },
                        "capacity": [
                            {
                                "cruiseID": "00001",
                                "total": null,
                                "available": 25
                            },
                            {
                                "cruiseID": "00002",
                                "total": null,
                                "available": 25
                            }
                        ]
                    },
                    {
                        "roomID": "SD2",
                        "roomDetails": {
                            "roomType": "asd",
                            "title": "and",
                            "description": "Fast",
                            "maxOccupants": 4
                        },
                        "capacity": [
                            {
                                "cruiseID": "00001",
                                "total": null,
                                "available": 22
                            },
                            {
                                "cruiseID": "00002",
                                "total": null,
                                "available": 22
                            }
                        ]
                    },
                    {
                        "roomID": "SJS",
                        "roomDetails": {
                            "roomType": "asd",
                            "title": "and",
                            "description": "Tasdr",
                            "maxOccupants": 4
                        },
                        "capacity": [
                            {
                                "cruiseID": "00001",
                                "total": null,
                                "available": 27
                            },
                            {
                                "cruiseID": "00002",
                                "total": null,
                                "available": 27
                            }
                        ]
                    },
                    {
                        "roomID": "SDS",
                        "roomDetails": {
                            "roomType": "asd",
                            "title": "and",
                            "description": "Tase",
                            "maxOccupants": 4
                        },
                        "capacity": [
                            {
                                "cruiseID": "00001",
                                "total": null,
                                "available": 20
                            },
                            {
                                "cruiseID": "00002",
                                "total": null,
                                "available": 20
                            }
                        ]
                    }
                ]
            },

而不是根据 Cruises 集合中的条目仅列出 CruiseID 00001 的 2 种房间类型(IPD、SDS)。

【问题讨论】:

  • Cruise.roomTypes (subfield) resolver then 'cruises' collection (not 'rooms') find by root.id (cruise) "cruiseID" : root.id ... 已经是一个数组 ...然后在循环中按容量条目匹配 Cruiseid 的类型查找房间
  • 感谢您的评论。但是,我不明白你的评论。你能解释一下吗?
  • Resolver chains 在这里试试:apollographql.com/docs/apollo-server/data/resolvers/…。遵循代码示例(否则有点难以理解这个想法)。 Library & Books (在你的情况下Cruise & Rooms)
  • Cruise = { roomTypes .... roomTypes 已在 Query.Cruises 中解决(部分 - 仅来自游轮条目的 roomId 道具 - 覆​​盖,也许你想要一些“房间”道具?) ?控制台日志(数据)? ...您需要解决“缺少”房间类型属性(roomDetails,容量)... Room.roomDetails 解析器将使用 roomID 获取房间作为父级(但阿波罗缓存需要每个类型的“id”/“_id”唯一字段 -房间详情)
  • 请在问题中查看我的更新。我正在解决房间类型。我只是无法在其中获取正确的数据。

标签: node.js mongodb express graphql apollo


【解决方案1】:

这就是我最终做到的方式。这不是最干净的代码/解决方案,但它可以完成工作。

const Cruise = {
  roomTypes: async (root) => {
    let rooms = root.roomTypes;
    allRooms = await db.collection('rooms').find().toArray().then(res => { return res });
    rooms.forEach(room => {
      let currentRoomID = room.roomID;
      currentRoom = allRooms.filter(function(r) {
        return r.roomID === currentRoomID;
      });
      currentRoomCapacity = currentRoom[0].capacity.filter(function(c) {
        return c.cruiseID === root.cruiseID;
      });
      room.roomDetails = currentRoom[0].roomDetails
      room.capacity = currentRoomCapacity
    });
    return rooms;
  }
}

【讨论】:

    猜你喜欢
    • 2019-06-07
    • 1970-01-01
    • 2017-08-22
    • 2021-03-21
    • 2019-06-12
    • 1970-01-01
    • 2020-06-11
    • 2022-08-22
    • 2011-12-08
    相关资源
    最近更新 更多