【问题标题】:mongoose geoindex failure when nested嵌套时猫鼬地理索引失败
【发布时间】:2016-05-27 06:43:38
【问题描述】:

我正在尝试根据与另一个集合中给定对象的地理接近度来检索一组 mongodb 记录。我正在使用 bluebird 来提供承诺。但是,当我的查询嵌套在 find 的 .then 子句中时,geoindex 搜索会失败 - 它似乎既不会引发 .catch 错误,也不会触发其中的代码。

router.post("/alert", function(req, res) {

    User.findOneAsync ({'loc.coordinates' : {
        $near : {
            $geometry : {
                type: "Point",
                "coordinates" : [45.001,45.001]
            },
            $maxDistance : 1000000
        }
    }}).then(function(users) {
        console.log("users actually are " + users)
    })

    Event.findAsync({
        _id : req.body.eventId
    }).then(function(evt) {
        console.log(evt)
        User.findAsync({'loc.coordinates' : {
            $near : {
                $geometry : {
                    type: "Point",
                    "coordinates" : [45.001,45.001]
                },
                $maxDistance : 1000000
            }
        }}).then(function(users) {
            console.log("users are " + users)
        }).catch(function(err) {
            console.log(err)
        })
        console.log('done')
    }).catch(function(err) {
        console.log(err)
    })
    res.send('ok')

})

调用时,直接对用户的第一次查询会成功。这是我可以在 mongodb 控制台中运行的相同查询,并获得相同的结果。但是第二个,在检索事件时,.then(function(evt)) 块中的任何代码都不会发生,并且 .catch 也不会被触发。

这是一个更大的问题,因为我需要使用的坐标实际上来自Event 模型,所以我需要检索该信息以实际查询Users...

这条线,console.log(evt) 确实运行了。

【问题讨论】:

  • 你知道 mongoose 4.x 版本本身就支持 Promise。另外,在这种情况下,为什么要嵌套 .then() 而不仅仅是继续承诺链( Event -> User -> Result )?
  • 确保你的Event.findAsync确实在返回promise,如果是,确保promise的条件是好的,否则不能被链接。您可能需要首先通过解决/拒绝它来操纵该承诺,或者您可能只需要返回它。如果它是一个好的 Promise,那么如果它作为一个 Promise 被正确传递,下一个 then 就会触发,无论是哪个库。如果您在捕获之前出错,那么您需要更仔细地分析 Event.findAsync,因为它正在死去。
  • 现在依赖于库的是你把你的catch放在哪里,也要小心。这里的脚手架也展示了一种如何捕获这些错误的方法github.com/wolfdogg/expressBuilder/blob/master/src/controllers/…

标签: node.js mongodb express bluebird geo


【解决方案1】:

在 Mongoose 4.x 中,您可以插入任何 Promise 库供 Mongoose 使用。我不确定您的 findAsync 方法是否真的返回了一个承诺,即使它定义了 .then() 方法。

来自猫鼬文档:

 // Use bluebird
 mongoose.Promise = require('bluebird');

然后您可以通过调用 .find(query).exec(); 来调用任何 Mongoose 查询,这将返回一个完整的蓝鸟承诺。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 2018-08-19
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 2019-01-16
    • 2021-03-23
    相关资源
    最近更新 更多