Как выбрать родителя на основе значения детей, используя mon goose и GraphQL? - PullRequest
0 голосов
/ 19 марта 2020

Я пытаюсь получить что-то эквивалентное условному запросу JOIN, но затем с помощью GraphQL. Я использую Mon goose для своей модели базы данных и MongoDB в качестве базы данных.

Я проиллюстрирую мою проблему с помощью следующей схемы graphQL:

type Booking {
    _id: ID!
    client: Client!
    rooms: Room!
    activities: Activity!
    nrOfAdults: Int!
    arrivalDate: String!
    departureDate: String!
}

type Room {
  _id: ID!
  name: String!
  contents: String
  priceNight: Float!
  maxAdults: Int!
  reservations: [Booking]
}

Схема Mon goose :

const bookingSchema = new Schema(
  {
    client: {
      type: Schema.Types.ObjectId,
      ref: 'Client'
    },
    rooms: [{
      type: Schema.Types.ObjectId,
      ref: 'Rooms'
    }],
    nrOfAdults: {
      type: Number,
      required: true
    },
    arrivalDate: {
      type: Date,
      required: true
    },
    departureDate: {
      type: Date,
      required: true
    }
  },
  { timestamps: true }
);

const roomSchema = new Schema({
  name: {
    type: String,
    required: true
  },
  priceNight: {
    type: Number,
    required: true
  },
  maxAdults: {
    type: Number,
    required: true
  },
  reservations: [
    {
      type: Schema.Types.ObjectId,
      ref: 'Booking'
    }
  ]
});

Я могу запросить номера, например, если я хочу получить номера для 3 или более взрослых, я запускаю:

       Room.find({
         maxAdults: { $gte: 3 }
       });

Это прекрасно работает.

Однако я также хотел бы показать доступных номеров, что означает, что мне нужно наложить условие на объекты бронирования, которые хранятся в резервировании . Я думал, что это будет довольно просто, используя что-то вроде:

       Room.find({
         maxAdults: { $gte: 3 },
         reservations: { $elemMatch: { arrivalDate: { $gte: *some date*}}}
       });

Но он возвращает пустой массив, в то время как он должен возвращать некоторое значение, основанное на данных в mongodb:

Чтобы сделать немного яснее, я бы хотел получить тот же результат, что и следующий запрос SQL:

SELECT *
FROM room
JOIN booking ON room.id = booking.roomId
WHERE
room.maxAdults >= 3
AND
(
booking.arrivalDate > CAST('2020-05-15' AS DATE)
OR
booking.departureDare < CAST(2020-05-06' AS DATE)
)

1 Ответ

0 голосов
/ 19 марта 2020

Предполагая, что вы сохранили значения, аналогичные тем, которые вы упомянули в схеме mon goose.

Узнайте, как сделать соединение в mongodb. Цель состоит в том, чтобы выполнить объединение перед выполнением запроса к подполям из другой коллекции.

Соответствующий ответ: Как выполнить эквивалент SQL Соединения в MongoDB?

Я предлагаю использовать агрегатный конвейер для выполнения того, что вы хотите.

Предлагаемый код:

Room.aggregate([
    {
        $match: {
            maxAdults: { $gte: 3 }
        }
    },
    {
        $lookup: {
            from: "bookings",
            localField: "reservations",
            foreignField: "_id",
            as: "booking"
        }
    },
    {
        $unwind: '$booking'
    },
    {
        $match: {
          booking.arrivalDate: { $gte: *some date* }
        }
    },
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...