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
是页面的\u id,它几乎与标记集合中的任何文档都不匹配localField:“\u id”
- 尚不清楚
是否应计算标签或页面。我在下面的答案中假设了前者$group
- 所有的转换阶段——很难猜测其意图,所以我从下面的代码片段中排除了它们。为了简洁起见,还删除了排序限制阶段
/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
}
}
}
]);