gpt4 book ai didi

mongodb - mgo/mongodb : aggregate - find all and order by membercount however membercount is an array of member userids

转载 作者:IT王子 更新时间:2023-10-29 00:37:03 25 4
gpt4 key购买 nike

1条记录(社区)的表示:

{
"_id" : ObjectId("538a4734d6194c0e98000001"),
"name" : "Darko",
"description" : "Darko",
"subdomain" : "darko",
"domain" : "forum.dev",
"created" : ISODate("2014-05-31T21:18:44.764Z"),
"category" : "Art and Culture",
"owner" : "53887456d6194c0f5b000001",
"members" : [
"53887456d6194c0f5b000001"
]
}

和 Go 类型

Community struct {
Id bson.ObjectId `bson:"_id,omitempty" json:"id"`
Name string `json:"name"`
Description string `bson:",omitempty" json:"description"`
Subdomain string `bson:",omitempty" json:"subdomain"`
Domain string `json:"domain"`
Created time.Time `json:"created"`
Category string `json:"category"`
Owner string `json:"owner"`
Banned []string `bson:",omitempty" json:"banned"`
Members []string `json:"members"`
Moderators []string `bson:",omitempty" json:"moderators"`
Admins []string `bson:",omitempty" json:"admins"`
Logo string `bson:",omitempty" json:"logo"`
Stylesheets []string `bson:",omitempty" json:"stylesheets"`
Javascripts []string `bson:",omitempty" json:"javascripts"`
}

现在我想检索类别艺术与文化的所有社区的列表,并按成员数量排序,也就是members.length 在 js 或 len(Community.Members) 在 Go.

类似SELECT * FROM communities ORDER BY COUNT(members) WHERE category = 'Art and Culture'

我有一个自定义类型要填充或解码

CommunityDirectory struct {
Id bson.ObjectId `bson:"_id,omitempty" json:"id"`
Name string `json:"name"`
Description string `bson:",omitempty" json:"description"`
Subdomain string `bson:",omitempty" json:"subdomain"`
Domain string `json:"domain"`
Created time.Time `json:"created"`
Category string `json:"category"`
Logo string `bson:",omitempty" json:"logo"`
Membercount int64 `bson:"membercount" json:"membercount"`
}

到目前为止我有什么

func (ctx *CommunityContext) Directory() {
pipe := ccommunity.Pipe([]bson.M{bson.M{"membercount": bson.M{"$size": "members"}}})
iter := pipe.Iter()
result := CommunityDirectory{}
results := []CommunityDirectory{}
for {
if iter.Next(&result) {
results = append(results, result)
fmt.Println(result)
} else {
break
}
}
ctx.JSON(results)
}

但这行不通,因为

db.communities.aggregate(
[
{"membercount": {$size:"members"}}
]
)

Error("Printing Stack Trace")@:0
()@src/mongo/shell/utils.js:37
([object Array])@src/mongo/shell/collection.js:866
@(shell):3

uncaught exception: aggregate failed: {
"errmsg" : "exception: Unrecognized pipeline stage name: 'membercount'",
"code" : 16436,
"ok" : 0
}

因此,它应该找到所有内容,按成员数排序并分配一个新的“虚拟”字段成员数,但仅限于“艺术与文化”类别。

我发现 MongoDB 在这方面相当复杂。

  1. mongodb 查询是什么样的?

  2. 在 Go/mgo 中它看起来像什么?

最佳答案

当你刚接触聚合框架时,有几个概念需要习惯

管道在 shell 中的正确形式应该是这样的:

db.communties.aggregate([

// Match the documents first to filter and possibly make use of an index
{ "$match": {
"category": "Art and Culture"
}},

// You include all fields when adding another and you want all
{ "$project": {
"name": 1,
"description": 1,
"subdomain": 1,
"domain": 1,
"created": 1,
"category": 1,
"owner": 1,
"members": 1,
"memberCount": { "$size": "$members" }
}},

// $sort means "ORDER BY" in this case the ascending
{ "$sort": { "memberCount": 1 } },

// Optionally project just the fields you need in the result
{ "$project": {
"name": 1,
"description": 1,
"subdomain": 1,
"domain": 1,
"created": 1,
"category": 1,
"owner": 1,
"members": 1
}}
])

因此,除非您根本不想改变结构,否则确实没有“SELECT *”的直接等价物。在这里你需要添加一个字段“memberCount”所以你需要指定所有的字段。您可以使用 $$ROOT它复制文档中的所有字段,但您需要将其分配给 $project 中的另一个字段/属性,例如:

{ "$project": {
"_id": "$$ROOT",
"memberCount": 1
}}

但是现在您所有的“字段”当然都与它们不完全相同,并且都以 _id. 为前缀。但这是个人品味问题。

接下来要习惯的就是总是尝试使用 $match第一的。这不仅有助于减少在聚合管道的其余部分操作的文档,这也是您使用索引优化查询的唯一机会。一旦您用其他阶段修改文档,使用索引就结束了,因为这不再是被索引的原始来源。实际上与 SQL 并没有太大区别,但语义在您指定的方式上有所不同。请记住,“管道”就像一个 Unix“管道”| 运算符,所以先进行“匹配”。

排序有它自己的流水线阶段。所以使用 $sort管道阶段的运算符(operator)来执行此操作。

决赛$project是可选的。这里我们只是丢弃了用于“排序”的“memberCount”字段。


mGo 的用法应该是这样的:

pipeline := [].bson.D{
bson.M{"$match": bson.M{ "category": "Art and Culture" } },

bson.M{"$project": bson.M{
"name": 1,
"description": 1,
"subdomain": 1,
"domain": 1,
"created": 1,
"category": 1,
"owner": 1,
"members": 1,
"memberCount": bson.M{ "$size": "$members" }
}},

bson.M{ "$sort": bson.M{ "memberCount": 1 } },

bson.M{ "$project": bson.M{
"name": 1,
"description": 1,
"subdomain": 1,
"domain": 1,
"created": 1,
"category": 1,
"owner": 1,
"members": 1
}}
}

pipe := ccommunity.Pipe( pipeline )

所以实际上与您会发现的大多数示例的形式没有什么不同。

可能看看SQL to aggregation Mapping Chart核心文档中提供了其他适用于聚合管道的常见 SQL 查询示例。

关于mongodb - mgo/mongodb : aggregate - find all and order by membercount however membercount is an array of member userids,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23983902/

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