Javascript MongoDB-在尝试基于查询字符串查找文档时,如何转换.或聚合等效项?

Javascript MongoDB-在尝试基于查询字符串查找文档时,如何转换.或聚合等效项?,javascript,node.js,mongodb,mongoose,aggregation-framework,Javascript,Node.js,Mongodb,Mongoose,Aggregation Framework,工作响应的示例(标记文档): 这是我的原始代码: Tag.find({}) .or({label: new RegExp(config.query, 'i')}) .sort(config.sortBy) .limit(config.limit) .skip(config.offset) .exec((err, tags) => {}); 这非常有效,但是我遇到了这样一个场景:这种方法不起作用(与问题无关) 这个重写的代码还将包括页面文档,特别是标签数组。下面是一个示

工作响应的示例(
标记
文档):

这是我的原始代码:

Tag.find({})
  .or({label: new RegExp(config.query, 'i')})
  .sort(config.sortBy)
  .limit(config.limit)
  .skip(config.offset)
  .exec((err, tags) => {});
这非常有效,但是我遇到了这样一个场景:这种方法不起作用(与问题无关)

这个重写的代码还将包括
页面
文档,特别是
标签
数组。下面是一个示例
页面
文档:

{
  "_id" : ObjectId("5a27a6b09fe2c00577821999"),
  "organisation" : ObjectId("5a17eb11bf3f990b94c01735"),
  "createdBy" : ObjectId("5a27a66f4db90e0541315114"),
  "createdAt" : ISODate("2017-12-06T08:13:36.199Z"),
  "updatedBy" : ObjectId("5a27a66f4db90e0541315114"),
  "updatedAt" : ISODate("2017-12-06T08:18:20.809Z"),
  "tags" : [ 
    ObjectId("5a27a6b09fe2c0057782199a"), 
    ObjectId("5a27a7859fe2c005778219a6"), 
    ObjectId("5a27a7859fe2c005778219a4")
  ],
  "content" : "asd",
  "description" : "asdasd",
  "title" : "testing tag creation",
  "parent" : null,
  "__v" : 0
}
这就是我现在拥有的:

Page.aggregate([
  {
    $unwind: "$tags"
  },

  // This bit ain't working
  {
    $match: {
      $or: [{
        label: new RegExp(config.query, 'i')
      }]     
    }
  },

  {
    $group: {
      _id: "$tags", 
      occurrences: {
        $sum: 1
      }
    }
  },
  {
    $lookup: {
      from: "tags", 
      localField: "_id", 
      foreignField: "_id", 
      as: "tagsData" 
    }
  },
  {$limit: config.limit},
  {$skip: config.offset},
  {$sort: {[config.sortBy]: config.order}},
  {
    $project: {
      occurrences: "$occurrences",
      tagData: {
        $arrayElemAt: [
          "$tagsData", 0 
        ]
      }
    }
  },
  {
    $addFields: {
      "tagData._id": "$_id", 
      "tagData.occurrences": "$occurrences" 
    } 
  }, 
  { 
    $replaceRoot: { 
      newRoot: "$tagData" 
    } 
  }
  ], (err, tags) => {
    console.log(tags);
  });
我要做的是替换这个位:

.or({label: new RegExp(config.query, 'i')})
在聚合框架中使用等效项

我在上面的尝试总是产生一个空数组,即使我做了
$match:{label:'05'}
例如,我没有得到任何结果

我一直在检查文档,但它们对我来说并不明显,因为这是我第一次使用聚合

我看过这两个:


所以我的问题是,我在查询位上做错了什么?

正如我在注释
Tag.find({})或({label:new RegExp(config.query,'I')})中提到的那样,
对我来说没有任何意义,聚合管道的大部分也没有意义

我将在回答中指出的几个显而易见的问题:

  • 页面
    只有标签的Id,因此应在标签可用的
    $lookup
    阶段之后按标签进行
    $match
    匹配
  • 从v3.3开始,在
    $lookup
    之前不需要
    $unwind
  • $lookup
    本身引用了错误的字段
    localField:“\u id”
    是页面的\u id,它几乎与标记集合中的任何文档都不匹配
  • 尚不清楚
    $group
    是否应计算标签或页面。我在下面的答案中假设了前者
  • 所有的转换阶段——很难猜测其意图,所以我从下面的代码片段中排除了它们。为了简洁起见,还删除了排序限制阶段
shell查询用于计算标签与regexp
/05/i
匹配的标签在所有页面上使用的次数:

db.pages.aggregate([
  {
    $lookup: {
      from: "tags", 
      localField: "tags", 
      foreignField: "_id", 
      as: "tagsData" 
    }
  },
  {
      $unwind: "$tagsData"
  },
  { 
      $match: {
          "tagsData.label": /05/i
      }
  },
  {
    $group: {
      _id: "$tagsData", 
      occurrences: {
        $sum: 1
      }
    }
  }
]);

没什么。原始查询
Tag.find({}).or({label:new RegExp(config.query,'i')})
对我来说毫无意义
Tag.find({})
匹配所有文档,因此之后的任何
都是多余的。这同样适用于聚合匹配阶段。您所指的文档读取
$或
数组时至少有2个元素。最后,聚合要比原始查询复杂得多。它使用2个集合,因此建议也提供第二个集合中的示例文档。@AlexBlex这不是多余的,
将筛选出与查询字符串不匹配的结果。如果这是正确的方法,我不知道,但是接线员在那里是有原因的,所以我认为你可以这样做。数组中有多个元素,但我将它们删掉,请参见示例中的
位。我现在已经包括了
页面
文档,请看一看。不,恐怕不会。您将逻辑析取的
、布尔
+
或变更(无论您喜欢什么术语)与逻辑连词的
或布尔
*
或交叉混淆。前者不限制任何符合先前条件的内容。@AlexBlex那么为什么它会返回我期望的结果呢?不管怎样,因为这是旧代码,问题更多的是如何重写它,“先前”代码会返回所有内容。如果您对此满意,只需删除管道中的匹配阶段。我相信问题出在查找阶段,如果您提供了您正在查询的页面集合中的示例文档,我可以为您提供更实用的建议。您添加到问题中的架构并不完全是一个文档,您正试图将它与问题中的标记
连接起来。好的,这是可行的。必须进一步修改一些内容,以适应
tagsData
的展开,使其工作。你知道为什么排序没有任何作用吗?我做了
$sort:{label:1(或-1)}
但它没有任何效果。因为没有
标签可以排序?如果在
$group
之后进行排序,则必须是
$sort:{“\u id.label”:1(或-1)}
。将排序移到底部可以工作。我还注意到,
localField:“tags”
应该是
localField:“\u id”
,否则它会断开,所以我会编辑你的答案。对不起,这是完全错误的。请阅读我在上面的回答中已经解释了为什么
localField:“\u id”
是错误的。我回复您的更改,并欢迎您发布您自己的答案,您认为这些答案可以解决您的问题。我只是告诉您哪些有效,哪些无效,您的解决方案无效,因此我无法接受。我理解您的解释,为什么它不应该工作,但我不能说为什么您的解决方案不工作,并且使用
\u id
是。
db.pages.aggregate([
  {
    $lookup: {
      from: "tags", 
      localField: "tags", 
      foreignField: "_id", 
      as: "tagsData" 
    }
  },
  {
      $unwind: "$tagsData"
  },
  { 
      $match: {
          "tagsData.label": /05/i
      }
  },
  {
    $group: {
      _id: "$tagsData", 
      occurrences: {
        $sum: 1
      }
    }
  }
]);