【问题标题】:Query mongoose model using variable as key in nested document使用变量作为嵌套文档中的键查询猫鼬模型
【发布时间】:2018-04-18 16:37:26
【问题描述】:

我在使用 model.find 返回与嵌套模式中的变量条件匹配的文档列表时遇到了一些问题。我在这个项目中使用 node、express 和 mongoose。

理想情况下,我想在查询中使用一个变量作为对象键,这样我就可以动态地获取星期几并检查营业时间。到目前为止,我还没有成功地在网上找到答案。

这是我的模型。

const restaurantSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    name: { type: String, required: true },
    coordinates: {
        latitude: { type: Number, required: true },
        longitude: { type: Number, required: true }
    },
  happy_hour: {
      sunday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      monday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      tuesday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      wednesday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      thursday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      friday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      },
      saturday: {
          open: { type: Boolean },
          open_at: { type: Number },
          close_at: { type: Number }
      }
  }
});

这是来自控制器的一个 sn-p,它正在处理此快速路由的逻辑。下面的 sn-p 有一个名为“Friday”的静态键,但我想动态获取星期几并将其作为变量传递,例如 $friday: { open: true } 或其他什么。

exports.search = (req, res, next) => {
    const radius = req.query.radius || 5;
    const latitude = req.query.latitude;
    const longitude = req.query.longitude;
    const day = date.get_day();
    const minutes = date.get_minutes();
    console.log(query[day]);
    if ( latitude == undefined || longitude == undefined ) {
        res.status(404).json({
            message: "Missing longitude or latitude"
        })
    }
    Restaurant.find({ 
        hours: {
            friday: {
                open: true
            }
        }
    })
        .exec()
        .then(results => {
            res.status(200).json({
                data: results.map( result => {

【问题讨论】:

  • 也许您可以将查询构建为字符串(使用字符串插值),然后将其解析为 JSON:query = JSON.parse("{hours: {``$day``: {open: true}}}")
  • 我不熟悉该语句中的语法$day。它是如何工作的?

标签: mongodb express mongoose


【解决方案1】:

你可以试试这个

var day = req.params.dayName;
var query = {};
query["hours"] = {[day] :true};
collection.find(query, function (err, item) { ... });

【讨论】:

  • 我不得不将查询更改为 {[day]: { open: true }} 以使用我上面的示例,但话虽如此,查询返回的结构与我的架构相同,但日期正确,但是,查询没有返回任何结果。我在 mongo 中肯定有一些数据应该为此查询返回。有任何想法吗?我注意到日期是大写的,所以我将它设置为小写,它没有效果。
  • console.log 将查询显示为{ hours: { wednesday: { open: true } } },这是正确的。我在数据库中有将其设置为 true 的餐厅。
【解决方案2】:

您有多种选择。

mongoose 期望的查询只是一个对象。

const query = { hours : {} };
hours[getTheCurrentDay()].open = true;

// Or with es6

const query = { hours : { [getTheCurrentDay()] : { open : true } };

// Or with pure string

const query = { `hours.${getTheCurrentDay()}.open` : true };

Restaurant.find( query ).exec()...

【讨论】:

  • 使用这些选项是否有任何性能优势?
  • 如果不做任何性能,我会说性能差异微不足道。不过,您应该问自己,哪一个对您的代码库更具可读性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-09
  • 2021-03-23
  • 2018-06-23
  • 2020-05-23
  • 2018-10-13
相关资源
最近更新 更多