Mongodb 如何使用Mongoose获取具有多个非独占选择器的mongo文档?

Mongodb 如何使用Mongoose获取具有多个非独占选择器的mongo文档?,mongodb,mongoose,mongodb-query,Mongodb,Mongoose,Mongodb Query,我需要构建一个查询来返回: 来自其ID的文档(可选) 与文本搜索字符串匹配的文档(可选) 其他文档按分数排序,计数受整数参数限制 总限制是提供的限制+第一个条件的文档数组ID的长度 我曾经使用meteor,在那里你可以返回一系列的查询和游标。在本例中,我使用的是mongoose后端,我不确定如何继续。我假设我需要使用Model.aggregate,并将我的条件作为数组提供。但是,请求失败,错误为参数必须是聚合管道运算符 通过常规的find()查询,我的每个条件都可以单独正常工作 这是我的gr

我需要构建一个查询来返回:

  • 来自其ID的文档(可选)
  • 与文本搜索字符串匹配的文档(可选)
  • 其他文档按分数排序,计数受整数参数限制
总限制是提供的限制+第一个条件的文档数组ID的长度

我曾经使用meteor,在那里你可以返回一系列的查询和游标。在本例中,我使用的是mongoose后端,我不确定如何继续。我假设我需要使用
Model.aggregate
,并将我的条件作为数组提供。但是,请求失败,错误为
参数必须是聚合管道运算符

通过常规的
find()
查询,我的每个条件都可以单独正常工作

这是我的graphQL查询解析器,我找不到哪里出了问题:

async(根,{search,selected=0,limit=10},{models:{tag}})=>{
试一试{
如果未设置其他条件,则let selector=[{}]/{}默认情况下应返回文档
if(selected.length)selector.push({u id:{$in:selected})
if(search&&search.length)selector.push({
$text:{
$search:search,
$区分大小写:错误,
$diacriticSensitive:错误
}
})
const tags=wait tag.aggregate(selector).sort('-score').limit(limit+selected.length)
返回{
好的,没错,
消息:“已获取标记”,
数据:标签
}
}catch(err){return{ok:false,message:err.message};}
}
),
当我记录设置了所有参数的选择器时,它返回以下形式的数组:

[
{},
{{u id:{'$in':[Array]},
{
“$text”:{
“$search”:“test”,
“$caseSensitive”:错误,
“$diacriticSensitive”:错误
}
}
]

更新

基于@ash answer,再加上一个
$或
运算符,完整的agregator变量如下所示:

   {
    '$match': {
      '$or': {
        _id: {
          '$in': [ '5e39745e0ac14b1731a779a3', '5e39745d0ac14b1731a76984' ]
        },
        '$text': {
          '$search': 'test',
          '$caseSensitive': false,
          '$diacriticSensitive': false
        }
      }
    }
  },
  { '$sort': { score: -1 } },
  { limit: 12 }
我仍然得到了“参数必须是聚合管道操作符”错误,并且我不知道如果
$text
参数不存在,我会在哪里按分数得到默认文档

@阿什,我会等你更新的答案来验证它。再次感谢您的帮助。

Mongoose
aggregate()
函数使用
$match
阶段,它相当于
find()
,但接受一些阶段作为元素数组来过滤文档。您可以在这里查看示例

剩下的就是你的代码错误。应该是

async (root, { search, selected = 0, limit = 10 }, { models: { tag } }) => {
  try {
    const aggregate = []
    let selector = { $match: { }};
    aggregate.push(selector)
    if (selected.length) {
      aggregate[0].$match['$or'] = [];
      aggregate[0].$match.$or.push({ _id: { $in: selected }});
    }
    if (search && search.length) {
      aggregate[0].$match['$or'] = aggregate[0].$match['$or'] ? aggregate[0].$match['$or'] : []
      aggregate[0].$match.$or.push({ $text: {
        $search: search,
        $caseSensitive: false,
        $diacriticSensitive: false
      }})
    }
    aggregate.push({ $sort: { score: - 1 }})
    aggregate.push({ $limit: limit })
    const tags = await tag.aggregate(aggregate)
    return {
      ok: true,
      message: "Tags fetched",
      data: tags
    };
  } catch (err) {
    return { ok: false, message: err.message };
  }
};