【问题标题】:Sequelize - Get all data with custom whereSequelize - 使用自定义 where 获取所有数据
【发布时间】:2020-07-13 15:53:29
【问题描述】:

如何使用自定义 where 条件获取数据?在这个问题Sequelize - function on column in a where clause, 我也有类似的问题,但我相信这个问题使用 MySQL 内置函数,它会在半径范围内获取数据。


我有几个模型。

  1. 房子
  2. 地址
  3. 任务

每个house 有很多 tasks。每个house 有一个 address

当调用/getTasks 时,我需要获得所有任务,但有以下约束:

房屋地址直线距离必须距离请求的经纬度 N 公里。

我可以使用findAndCountAll 轻松完成此操作,然后在将结果返回给客户端之前进行计算,但我确信这会运行得更慢/效率更低,或者这会破坏分页。


这是我目前所拥有的:

// Get all the available tasks.
// Requirements:
// 1. It accepts the coordinate from the client.
// 2. The client's coordinate must be <= N-Kilometer straight distance.
// 3. Return the tasks WITH PAYMENT and WITHOUT assigned USER.
exports.getTasks = (req, res) => {
  const latitude = parseFloat(req.query.latitude)
  const longitude = parseFloat(req.query.longitude)

  if (!longitude || !latitude) {
    return res.status(200).send({
      errorCode: 101,
      message: "Error! Required parameters are: {longitude} and {latitude}."
    })
  }

  const page = myUtil.parser.tryParseInt(req.query.page, 0)
  const limit = myUtil.parser.tryParseInt(req.query.limit, 10)

  const houseLat = 32.9697
  const houseLong = -96.80322

  console.log("Computing distance of a house (" + latitude + ", " + longitude + ") --- to (" + houseLat + ", " + houseLong + ")")

  point1 = new GeoPoint(latitude, longitude)
  point2 = new GeoPoint(pLat, pLong)

  const distance = point1.distanceTo(point2, true)

  // Begin query...
  db.Task.findAndCountAll({
    where: null, // <----- don't know what to put.
    include: [
      {
        model: db.Order,
        as: "order"
      },
      {
        model: db.House,
        as: "house",
        include: [
          {
            model: db.Address,
            as: "address"
          }
        ]
      }
    ],
    offset: limit * page,
    limit: limit,
    order: [["id", "ASC"]],
  })
    .then(data => {
      res.json(myUtil.response.paging(data, page, limit))
    })
    .catch(err => {
      console.log("Error get all tasks: " + err.message)
      res.status(500).send({
        message: "An error has occured while retrieving data."
      })
    })
}

【问题讨论】:

  • 澄清一下,您是否要查找请求位置的特定半径范围内的所有房屋?
  • 是的!但我真的更喜欢直线距离,而不是那个半径的东西。获取所有房屋,前提是房屋与用户的直线距离为
  • 这有点超出我的舒适范围,因为您需要使用地理空间查询。再澄清一次,您要在 A 点和 B 点之间的线的 X-KM 范围内寻找任何东西?
  • 我认为地理空间查询的事情在我上面发布的类似问题中。但这并不像我说的那样是必要的,是的,只是 ptA 和 ptB 之间的直线距离/直线。我的问题中的代码已经可以计算直线距离,不需要花哨的 Google API 或其他东西。我只是在想也许我可以把计算的东西挂到我的“哪里”条件中。还是不可能?
  • 当然!顺便说一句,我错误地讨论了我试图获得“房屋”而不是获得“任务”。

标签: node.js express sequelize.js


【解决方案1】:

我在这里发布我的解决方案。为了提供更多背景信息,这个休息应用程序就像一个寻找每个房子的女佣/帮手的工具。这个特定的端点(问题)是为女佣/助手客户端应用程序获取需要清洁的可用房屋列表。条件是:

  1. 房屋必须与客户端应用所在位置直线距离在 10 公里以内。
  2. 任务没有指定的清洁工。

所以在这个解决方案中,我再次摆脱了分页 - 这有点复杂。在我看来,对于这种特定类型的应用程序设计(报价、工作和诸如此类的列表),您不需要分页。然后从字面上计算直线距离。无需 Google API。无需地理空间查询。我在这里可能错了,但这就是我想要的 -

// Get all the available tasks.
// We are not using pagination here...
// Makes our lives easier.
// Requirements:
// 1. It accepts the coordinate from the client.
// 2. The client's coordinate must be <= N-Kilometer straight distance.
// 3. Return the tasks WITH ORDER and WITHOUT USER.
exports.getAvailableMissions = (req, res) => {
  const latitude = parseFloat(req.query.latitude)
  const longitude = parseFloat(req.query.longitude)

  if (!longitude || !latitude) {
    return res.status(200).send({
      errorCode: 101,
      message: "Error! Required parameters are: {longitude} and {latitude}."
    })
  }

  // Proceed with searching...
  // user id must equal to null. - means unassigned.
  // order must not be equal to null. - means paid.
  // the order condition is in the promise.
  const condition = { userId: { [op.is]: null } }

  // Begin query...
  db.Mission.findAndCountAll({
    where: condition,
    include: [
      {
        model: db.Order,
        as: "order"
      },
      {
        model: db.Asset,
        as: "asset"
      },
      {
        model: db.House,
        as: "house",
        include: [
          {
            model: db.Address,
            as: "address"
          }
        ]
      }
    ],
    limit: 10,
    order: [["id", "ASC"]],
  })
    .then(data => {
      let newData = JSON.parse(JSON.stringify(data))
      const tasks = newData.rows
      let newRows = []

      for (let task of tasks) {
        const house = task.house
        const address = house.address
        const houseLat = address.latitude
        const houseLong = address.longitude

        const point1 = new GeoPoint(latitude, longitude)
        const point2 = new GeoPoint(houseLat, houseLong)

        const distance = point1.distanceTo(point2, true)
        const distanceInMiles = distance * 0.621371

        console.log("Computing distance (" + latitude + ", " + longitude + ") --- to (" + houseLat + ", " + houseLong + ")")
        console.log("Miles: distance: ", distanceInMiles)

        // 10 miles max straight distance.
        const maxDistance = 10

        if (distanceInMiles <= maxDistance) {
          task.distanceFromMeInMiles = parseFloat(distanceInMiles)
          newRows.push(task)
        }
      }

      // Apply the new rows.
      delete newData.rows
      delete newData.count
      newData.total = newRows.length
      newData.data = newRows

      res.json(newData)
    })
    .catch(err => {
      console.log("Error get all tasks: " + err.message)
      res.status(500).send({
        message: "An error has occured while retrieving data."
      })
    })
}

【讨论】:

    猜你喜欢
    • 2017-09-19
    • 2021-12-13
    • 1970-01-01
    • 2020-10-17
    • 2022-11-08
    • 2011-05-29
    • 2011-07-30
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多