Truy vấn tuần tự hóa với mệnh đề where trên bao gồm bao gồm


8

Tôi đang vật lộn để tạo một truy vấn với phần tiếp theo.

Một số bối cảnh

Tôi có các mô hình sau:

  • A Manifestationcó thể có [0..n]Event
  • An Eventthuộc về một Manifestation( Eventkhông thể tồn tại mà không có a Manifestation)
  • A Placecó thể có [0..n]Event
  • An Eventthuộc về một Place( Eventkhông thể tồn tại mà không có a Place)
  • A Manifestationcó thể có [1..n]Place
  • A Placecó thể có [0..n]Manifestation

Tôi mô hình các mối quan hệ như sau:

Manifestation.hasMany(Event, { onDelete: 'CASCADE', hooks: true })
Event.belongsTo(Manifestation)

Place.hasMany(Event, { onDelete: 'CASCADE', hooks: true })
Event.belongsTo(Place)

Manifestation.belongsToMany(Place, { through: 'manifestation_place' })
Place.belongsToMany(Manifestation, { through: 'manifestation_place' })

Đối với tôi nó có vẻ khá đúng, nhưng đừng ngần ngại nếu bạn có nhận xét.

Câu hỏi

Tôi đang cố gắng truy vấn Placeđể có được tất cả ManifestationEventxảy ra trong một nhất định Place. Nhưng đối với Eventnhững người, tôi muốn bao gồm họ trong họ Manifestationngay cả khi điều Manifestationđó không xảy ra trong cái đã cho Place.

Dưới đây là cấu trúc "JSON" mà tôi đang cố gắng đạt được:

{
  id: 1,
  name: "Place Name",
  address: "Place address",
  latitude: 47.00000,
  longitude: -1.540000,
  manifestations: [
    {
      id: 10,
      title: "Manifestation one",
      placeId: 1,
      events: []
    },
    {
      id: 11,
      title: "Manifestation two",
      placeId: 3,
      events: [
        id: 5,
        title: "3333",
        manifestationId: 11,
        placeId: 1
      ]
    }
  ]
}

Vì vậy, tôi muốn bao gồm Manifestationvới id: 11, vì một trong số đó Eventxảy ra trong phần đã cho Place(với id: 1)

Cập nhật (04/06/20): Hiện tại tôi dựa vào javascript để có được kết quả như mong đợi

Tôi nhận ra rằng nó sẽ tốt đẹp nếu tôi đăng giải pháp hiện tại của mình trước khi hỏi.

router.get('/test', async (req, res) => {
  try {
    const placesPromise = place.findAll()
    const manifestationsPromise = manifestation.findAll({
      include: [
        { model: event },
        {
          model: place,
          attributes: ['id'],
        },
      ],
    })

    const [places, untransformedManifestations] = await Promise.all([
      placesPromise,
      manifestationsPromise,
    ])

    const manifestations = untransformedManifestations.map(m => {
      const values = m.toJSON()
      const places = values.places.map(p => p.id)
      return { ...values, places }
    })

    const result = places
      .map(p => {
        const values = p.toJSON()
        const relatedManifestations = manifestations
          .filter(m => {
            const eventsPlaceId = m.events.map(e => e.placeId)
            return (
              m.places.includes(values.id) ||
              eventsPlaceId.includes(values.id)
            )
          })
          .map(m => {
            const filteredEvents = m.events.filter(
              e => e.placeId === values.id
            )
            return { ...m, events: filteredEvents }
          })
        return { ...values, manifestations: relatedManifestations }
      })
      .filter(p => p.manifestations.length)

    return res.status(200).json(result)
  } catch (err) {
    console.log(err)
    return res.status(500).send()
  }
})

Nhưng tôi khá chắc chắn rằng tôi có thể làm điều đó trực tiếp với phần tiếp theo. Bất kỳ ý tưởng hoặc khuyến nghị?

Cảm ơn

Câu trả lời:


0

Điều này là không tối ưu. Nhưng bạn có thể dùng thử:

const findPlace = (id) => {
    return new Promise(resolve => {
        db.Place.findOne({
            where: {
                id: id
            }
        }).then(place => {
            db.Manefestation.findAll({
                include: [{
                    model: db.Event,
                    where: {
                        placeId: id
                    }
                }]

            }).then(manifestations => {
                const out = Object.assign({}, {
                    id: place.id,
                    name: place.name,
                    address: place.address,
                    latitude: place.latitude,
                    longitude: place.longitude,
                    manifestations: manifestations.reduce((res, manifestation) => {
                        if (manifestation.placeId === place.id || manifestation.Event.length > 0) {
                            res.push({
                                id: manifestation.id,
                                title: manifestation.id,
                                placeId: manifestation.placeId,
                                events: manifestation.Event
                            })
                        }
                        return res;
                    }, [])
                })
            })
            resolve(out);
        })
    })
}

Từ đó, bạn nhận được tất cả các biểu hiện được chỉ định để đặt hoặc có bất kỳ sự kiện nào được chỉ định. Tất cả các sự kiện bao gồm trong các biểu tượng được chỉ định đến nơi.

Chỉnh sửa: Bạn cũng sẽ có thể sử dụng một trong những điều sau đây:

const findPlace = (id) => {
    return new Promise(resolve => {
        db.Place.findOne({
            include: [{
                model: db.Manefestation,
                include: [{
                    model: db.Event,
                    where: {
                        placeId: id
                    }
                }]

            }],
            where: {
                id: id
            }
        }).then(place => {
            db.Manefestation.findAll({
                include: [{
                    model: db.Event,
                    where: {
                        placeId: id
                    }
                }],
                where: {
                    placeId: {
                        $not: id
                    }
                }

            }).then(manifestations => {
                place.Manefestation = place.Manefestation.concat(manifestations.filter(m=>m.Event.length>0))
                resolve(place);// or you can rename, reassign keys here
            })
        })
    })
}

Ở đây tôi chỉ có các biểu hiện trực tiếp trong truy vấn đầu tiên. Sau đó, các biểu hiện không bao gồm và nối.


Cảm ơn câu trả lời của bạn, đó là những gì tôi thực sự làm, và tôi đang tìm kiếm một cách làm tiếp theo thay vì một cách đơn giản.
xavier.seignard

bạn có thể thực thi SQL truy vấn SQL
Nilanka Manoj

Sau khi xem giải pháp của bạn, nó không thực hiện những gì tôi đang tìm kiếm. Đọc lại cẩn thận câu hỏi của tôi
xavier.seignard

Xin lỗi vì điều đó, tôi đã chỉnh sửa câu trả lời ngay bây giờ
Nilanka Manoj

Có một số lỗi chính tả trong câu trả lời đầu tiên và tôi đã chỉnh sửa nó. Ngoài ra, tôi cũng đã thêm một câu trả lời mới
Nilanka Manoj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.