MongoDB:对文档集进行设置操作,如何?

时间:2018-07-14 20:14:08

标签: javascript sql mongodb

在MongoDB中可以这样做吗?

select id, title from posts
union all
select id, name from programs
sort by title asc;

我想对来自两个不同集合的文档进行排序,并将结果视为一个集合。请帮忙。

已添加

事实上,我正在进行文本搜索,但是我想搜索2个集合并合并结果:

我的快速路线处理程序如下:

// Post and Program are a Mongoose models
function (req, res) {
  const criteria = req.params.criteria

  Promise.all([
    Post
      .find({$text: {$search: criteria}}, { title: 1, score: { $meta: 'textScore' }})
      .sort({ score: { $meta: 'textScore' } })
      .exec(),

    Program
      .find({$text: {$search: criteria}}, { title: 1, score: { $meta: 'textScore' }})
      .sort({ score: { $meta: 'textScore' } })
      .exec()
  ])
    .then(results => reply([...results[0], ...results[1]]))
    .catch(err => handle(err))
}

我知道我可以像使用lodash一样操作结果数组,但是问题是我必须一页一页地显示结果,因此对于每个请求,我都应该获取每页显示的文档数。

如果我选择lodash,那么我将始终从数据库中获取所有数据,然后使用lodash选择正确的页面。只需获取所需的内容,就会更有效率。

所以我希望有一种方法可以做到这样:

Post
  .find({$text: {$search: criteria}}, { title: 1, score: { $meta: 'textScore' }})
  .unionAll(
    Program
      .find({$text: {$search: criteria}}, { title: 1, score: { $meta: 'textScore' }})
  )
  .sort({ score: { $meta: 'textScore' } })
  .limit(10)
  .exec()

我知道我在做梦,但这是有道理的。 那么有没有办法从MongoDB获得结果,还是我必须用lodash或类似的东西来管理它。

1 个答案:

答案 0 :(得分:1)

您可以尝试进行$facet$lookup聚合

db.collection.aggregate([
  { "$limit": 1 },
  { "$facet": {
    "c1": [
      { "$lookup": {
        "from": Post.collection.name,
        "pipeline": [
          { "$match": { "$text": { "$search": criteria }} },
          { "$project": { "title": 1 }}
        ],
        "as": "collection1"
      }}
    ],
    "c2": [
      { "$lookup": {
        "from": Program.collection.name,
        "pipeline": [
          { "$match": { "$text": { "$search": criteria }} },
          { "$project": { "name": 1 }}
        ],
        "as": "collection2"
      }}
    ]
  }},
  { "$project": {
    "data": {
      "$concatArrays": [ "$c1", "$c2" ]
    }
  }},
  { "$unwind": "$data" },
  { "$replaceRoot": { "newRoot": "$data" } }
])