之前一直使用MySQL,后面因为其他原因,需要使用mongodb,但是自己对mongodb又不是很熟悉
今天经历了一个算是我任务超级复杂的案例了
下面看下这个聚合的查询语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| db.table_name.aggregate([ { '$match': { 'dtime': 0 } }, { '$lookup': { 'as': 'content', 'localField': 'rule_id', 'foreignField': 'rule_id', 'from': 'table2' } }, { '$addFields': { starIDs: '$star_ids' } },
{ '$unwind': "$starIDs" },
{ '$addFields': { starIDStr: {$concat: [ "star_id::", {$toString: "$starIDs"}]} } },
{ '$unwind': "$content" },
{ '$match': { 'content.dtime': 0 } }, { '$lookup': { 'as': 'audit', 'localField': 'starIDStr', 'foreignField': 'person_id', 'from': 'table3' } },
{ '$group': { '_id': '$_id', 'doc': {"$first":"$$ROOT"},
} },
{ "$replaceRoot":{"newRoot":"$doc"} },
{ '$sort': { 'content.contents.0.ctime': -1, 'content.group_id': -1 } },
{ '$skip': 0 },
{ '$limit': 15 }, ]);
|
需求是这样的
首先用table_name表去关联table1,别名为content,通过rule_id去关联,之后需要关联另外一个表table3,但是table3这个表的字段跟table2表字段类型不一致
table2表字段是一个数组star_ids: [123,456]
table3表需要关联的字段是一个字符串,字段值举例子(person_id: 'star_id::123'
)
这个时候需要进行字段的类型转换,于是我们用到了addFields
管道工具,从上面的执行语句中可以看到,我们执行了一个unmind
操作,主要是为了将数组值转为字符串,
具体效果如下,从如下
变成了
也就是将
变成了
1 2
| star_ids: 123 star_ids: 456
|
这里注意下,转换后的结果是两条记录
但是我们有个要求就是不能更改原有字段类型,也就是
这个是不能修改的
于是我们重命名之后在进行字符串的拼接
最后 star_ids: [123,456]
(这个依然存在不会更改) 分身出来一个 starIDs: [123,456],同时因为unwind了starIDs,最后starIDS变成了
1 2
| starIDs: 123 starIDs: 456
|
然后就可以进行字符串的拼接了
1 2 3
| '$addFields': { starIDStr: {$concat: [ "star_id::", {$toString: "$starIDs"}]} }
|
最后starIDs变成了
1 2
| starIDs: 'star_id::123' starIDs:'star_id::456'
|
最后整理成了与person_id字段值规则一致的了,这样就可以就行查询了
也就有了
1 2 3 4 5 6 7 8
| { '$lookup': { 'as': 'audit', 'localField': 'starIDStr', 'foreignField': 'person_id', 'from': 'table3' } },
|
最后由于由
star_ids: [123, 456]
变成
star_ids: 123
star_ids: 456
的时候
记录条数由一条变成了两条,需要进行去重处理
于是用到了
1 2 3 4 5
| { '$group': { '_id': '$_id', } },
|
之后由于用到了group,是的记录不能返回所有的字段
于是由了下面这个管道
1 2 3 4 5 6 7 8 9 10 11
| { '$group': { '_id': '$_id', 'doc': {"$first":"$$ROOT"},
} },
{ "$replaceRoot":{"newRoot":"$doc"} },
|
最终解决了一个复杂的查询,可以说mongodb的管道工具还是很强大的,但是用起来也是超级复杂