MongoDB聚合管道:使用$ cond返回$ match阶段?

时间:2017-05-05 08:22:11

标签: mongodb

我正在尝试构建查询以实际上有趣的方式与数据库交互。其中之一是在一定年限内搜索文档。我的想法是建立一个聚合管道,我在其中检查是否在搜索表单中选择了年份范围,然后返回匹配的文档。如果未选择范围,则返回所有文档并转到聚合管道的下一阶段。

以下是我的尝试(aggregate中只有一个阶段,因为我还没有设法让第一个阶段工作,但是):

    db.collection('archives').aggregate([
      { $cond: { if: yearStart.length === 4 && yearEnd === 4 },
        then: { $match:
          { $and:
            [
              { year: {$gte: yearStart} },
              { year: {$lte: yearEnd} }
            ]
          }
        },
        else: { $match: {} }
      }
    ]).toArray( (err, docs) => {
      if (err) throw (err)
      res.json(docs)
    })

所以,这不起作用。我收到错误MongoError: A pipeline stage specification object must contain exactly one field.。所以我认为这只是将$cond声明括在curlies中。但不,不。我在unexpected token {崩溃了。所以我认为$cond可能不会像这样使用(返回$match阶段)。我倾向于这么认为,因为文档只显示了返回一个简单值的例子......是不是?

提前致谢!

1 个答案:

答案 0 :(得分:1)

首先使用原生JavaScript条件创建要在管道外使用 $match 的查询对象,因为使用 $cond 运算符仅适用在指定的管道阶段内。在这里你正在使用 它作为管道步骤因此抛出错误。

请考虑以下事项:

const query = { "year": { } };
if (yearStart.length === 4 && yearEnd === 4) {
    query["year"]["$gte"] = yearStart;
    query["year"]["$lte"] = yearEnd;    
}

db.collection('archives').aggregate([ { "$match": query } ]).toArray((err, docs) => {
    if (err) throw (err);
    res.json(docs);
});

或使用 find() 方法

db.collection('archives').find(query).toArray((err, docs) => {
    if (err) throw (err);
    res.json(docs);
});