gpt4 book ai didi

node.js - 计算某个字段在集合中出现的次数,同时保留所有数据不重复

转载 作者:太空宇宙 更新时间:2023-11-03 23:38:37 25 4
gpt4 key购买 nike

假设我有一个这样的集合:

{
_id : 544e97123c9ef694fc68e21b,
title: "First Title",
notebook: {
title: "Misc",
slug: "misc"
}
}
{
_id: 54ab035a849788d0921d8eb2,
title: "Second Title",
notebook: {
title: "Personal",
slug: "personal"
}
}
{
_id: 544e97123c9ef694fc68e21b,
title: "Third Title",
notebook: {
title: "Misc",
slug: "misc"
}
}

在我看来,我希望能够显示笔记本标题已被使用的次数以及指向该特定笔记本的 slug 的链接(不分特定顺序)。例如:

<a href="/notebooks/misc">Misc(2)</a>
<a href="/notebooks/personal">Personal(1)</a>

我通过浏览每个文档来实现这一点,但问题是它有重复,因为它正在浏览每个文档。所以在我看来,它看起来像这样:

<a href="/notebooks/misc">Misc(2)</a>
<a href="/notebooks/personal">Personal(1)</a>
<a href="/notebooks/misc">Misc(2)</a>

如何抓取notebook.title、notebook.slug,对它们进行计数,并且没有重复项?

这是我目前的做法(这会导致重复):

function countNotebooks(notes) {
var table = Object.create(null);
for (var i = 0; i < notes.length; i++) {
if (typeof table[notes[i].notebook.slug] === 'undefined') {
table[notes[i].notebook.slug] = 1;
} else {
table[notes[i].notebook.slug] += 1;
}
}
return table;
}

app.get('/notebooks', function(req, res) {
Note.find(function(err, notes) {
if (err) {
throw err;
}
res.render('notebooks/index.html', {
title: 'All Notebooks',
jumbotron: 'Notebooks',
notes: notes,
notesTable: countNotebooks(notes)
});
});
});

笔记本/index.html:

{% for note in notes %}
<article class="note">
<h3 class="note-title">
<a href="/notebooks/{{ note.notebook.slug }}">{{ note.notebook.title }}</a> <span class="count">({{ notesTable[note.notebook.slug] }})</span>
</h3>
</article>
{% endfor %}

最佳答案

您可以通过根据公用 key 对数据进行分组来实现此目的。 aggregation framework MongoDB 就是为这种聚合和操作而设计的。

首先,我可以更正您的数据样本吗,因为您有重复的 _id值,这是不允许的。

{
"_id" : ObjectId("544e97123c9ef694fc68e21b"),
"title" : "First Title",
"notebook" : {
"title" : "Misc",
"slug" : "misc"
}
},
{
"_id" : ObjectId("54ab035a849788d0921d8eb2"),
"title" : "Second Title",
"notebook" : {
"title" : "Personal",
"slug" : "personal"
}
},
{
"_id" : ObjectId("54ac074fa8a621d3fd49ac91"),
"title" : "Third Title",
"notebook" : {
"title" : "Misc",
"slug" : "misc"
}
}

要为数据中出现的“slug”添加“计数”值,您可以形成如下管道:

Note.aggregate([

// Group on the slug values and put other fields in an array
{ "$group": {
"_id": "$notebook.slug",
"count": { "$sum": 1 },
"docs": {
"$push": {
"_id": "$_id",
"title": "$title",
"notebook": "$notebook"
}
}
}},

// Unwind the created array elements
{ "$unwind": "$docs" },

// Re-structure back to original form
{ "$project": {
"_id": "$docs._id",
"title": "$docs.title",
"count": "$count",
"notebook": "$docs.notebook"
}},

// Sort in original order (or as desired)
{ "$sort": { "_id": 1 } }

],function(err,result) {

});

这会给你带来这样的结果:

{
"_id" : ObjectId("544e97123c9ef694fc68e21b"),
"count" : 2,
"title" : "First Title",
"notebook" : {
"title" : "Misc",
"slug" : "misc"
}
},
{
"_id" : ObjectId("54ab035a849788d0921d8eb2"),
"count" : 1,
"title" : "Second Title",
"notebook" : {
"title" : "Personal",
"slug" : "personal"
}
},
{
"_id" : ObjectId("54ac074fa8a621d3fd49ac91"),
"count" : 2,
"title" : "Third Title",
"notebook" : {
"title" : "Misc",
"slug" : "misc"
}
}

如果您想“保留文档”,但如果您只想要像“面数”这样的独特“slugs”,那么只需使用第一个 $group $first笔记本标题上的 而不是 $push 与其他内容:

Note.aggregate([

// Group on the slug values and put other fields in an array
{ "$group": {
"_id": "$notebook.slug",
"count": { "$sum": 1 },
"title": { "$first": "$notebook.title" }
}},
],function(err,result) {

});

它应该是相当不言自明的,但只是为了总结。初始 $group 使用“slug”的值来计算 $sum 的出现次数。运算符(operator)。为了保留文档数据的其余部分,将其放置在“slug”下的数组中,使用 $push .

分组后,使用 $unwind 将数组非规范化为文档,然后使用 $project 简单地重新构造回原始形式。决赛 $sort 操作提供原始顺序或您想要的任何内容,因为顺序在 $group 期间发生了更改。管道阶段。

这不仅可以获得结果,而且还允许您使用 $limit 对数据进行“分页”和 $skip 具有适当计数值的运算符,甚至根据需要根据这些计数值对数据进行排序。

查看完整的ggregation pipeline operator reference有关完整说明和其他可以在此处完成的操作。

关于node.js - 计算某个字段在集合中出现的次数,同时保留所有数据不重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27806604/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com