繁体   English   中英

MongoDB-尝试基于查询字符串查找文档时,如何将.or转换为等效的聚合?

[英]MongoDB - How to convert .or to aggregate equivalent when trying to find documents based on a query string?

工作回复示例( Tag文档):

[ 
  { 
    _id: 5a27a6b09fe2c0057782199a,
    label: '05',
    createdBy: 5a27a66f4db90e0541315114,
    createdAt: 2017-12-06T08:17:09.480Z,
    updatedAt: null,
    __v: 0,
    occurrences: 1 
  }, 
  ...
]

这是我的原始代码:

Tag.find({})
  .or({label: new RegExp(config.query, 'i')})
  .sort(config.sortBy)
  .limit(config.limit)
  .skip(config.offset)
  .exec((err, tags) => {});

这非常出色,但是我遇到了这种方法行不通的场景(与问题无关)。

这段重写的代码还将包含Page文档,特别是tags数组。 这是一个示例Page文档:

{
  "_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'}例如也没有结果。

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

我看了以下两个:

https://docs.mongodb.com/manual/reference/operator/aggregation/match/ https://docs.mongodb.com/manual/reference/operator/aggregation/or/

所以我的问题是查询位在做什么?

正如我在评论中提到的那样, Tag.find({}).or({label: new RegExp(config.query, 'i')})对我来说,对大多数聚合管道都没有意义。

我将在回答中针对管道中的一些明显问题:

  • Page仅具有ID的标签,因此应在$lookup阶段(可使用标签)之后执行$lookup tag by tag标签$match
  • 从v3.3开始,在$lookup之前无需$unwind
  • $lookup本身指向错误的字段localField: "_id"是页面的_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
      }
    }
  }
]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM