问题描述
我有一些集合,我正在尝试将日志对象转换为其详细信息(使用 populate
)。
Companies
(公司及其用户):
[
{
_id: "comp123",companyId: "compName123",users: [
{ user: "user111",status: "active"},{ user: "user222",]
},{
_id: "comp456",name: "compName456",users: [
{ user: "user333",status: "active"}
]
},{
_id: "comp789",name: "compName789",users: [
{ user: "user444",status: "inactive"}
]
},]
Users:
[
{_id: "user111",firstName: "userName111"},{_id: "user222",firstName: "userName222"},{_id: "user333",firstName: "userName333"},{_id: "user444",firstName: "userName444"},]
我正在尝试将 log
集合转换为数据。
examples:
对于 log
的第一个对象:
{
companyId: "comp123",actionDetails: [
entities: [
{ id: "user111",entityType: "User"}
]
]
},
我希望它返回:
{
companyId: {_id: "comp123",name: "compName123"},// taken from companies
userId: { _id: "user111",// taken from users
// Does company=comp123 that has a user with user=user111 and status=active exist?
isUserActiveInCompany: true
}
另一个日志示例:
{
companyId: "comp456",actionDetails: [
entities: [
{ id: "user444",entityType: "User"}
]
]
}
输出为:
{
companyId: {_id: "comp456",name: "compName456"},// taken from companies
userId: { _id: "user444",// taken from users
isUserActiveInCompany: false // Does company=comp456 that has a user with user=user444 and status=active exist?
}
最后一个重要的日志示例:
{
companyId: "comp789",actionDetails: [
entities: [
{ id: "attr333",entityType: "Attribute"}
]
]
}
输出:
{
companyId: {_id: "comp789",name: "compName789"},// taken from companies
userId: {},// taken from users (entityType is Attribute so we ignore it)
isUserActiveInCompany: null // entityType is Attribute so we ignore it
}
如果会有comp789和user444的日志,isUserActiveInCompany应该是false(因为用户在他的公司是不活跃的)。
目前,我这样做:
populate([
{
path: "actionDetails.entities.id",select: "id firstName",},{
path: "companyId",select: "name",]
感谢任何帮助!
解决方法
将下面的聚合管道代码转换为 Mongoose Equivalent 以获得您想要的输出。
db.log.aggregate([
{
'$match': {
// <-- I highly recommend that you use a `$match` condition since there are 2 lookup operators in the aggregation which will significantly increase execution time.
}
},{
'$lookup': {
'from': 'Companies','let': {'cId': '$companyId'},'pipeline': [
{
'$match': {
'$expr': {
'$eq': ['$_id','$$cId']
}
}
},{
"$project": {
'company': {
"_id": "$_id","companyName": "$companyId"
},'users': {
"$filter": {
'input': "$users",'as': "usr",'cond': {
"$eq": ["$$usr.status","active"],},}
},],'as': 'companyDetails'
}
},{
'$unwind': {
'path': "$actionDetails",}
},{
'$unwind': {
'path': "$actionDetails.entities",{
'$lookup': {
'from': 'Users','let': {"uId": "$actionDetails.entities.id"},'pipeline': [
{
"$match": {
"$expr": {
"$eq": ["$_id","$$uId"],{
"$project": {
"firstName": 1,'as': "userDetails",{
'$project': {
"companyId": {"$arrayElemAt": ["$companyDetails.company",0]},"userId": {
"_id": "$actionDetails.entities.id","firstName": {"$arrayElemAt": ["$userDetails.firstName","isUserActiveInCompany": {
"$switch": {
"branches": [
{
'case': {
"$ne": ["$actionDetails.entities.entityType","User"]
},'then': null,{
'case': {
"$in": [
"$actionDetails.entities.id",{
"$map": {
'input': {"$arrayElemAt": ["$companyDetails.users",'as': "elem",'in': "$$elem.user"
}
}
]
},'then': true,'default': false,}
}
}
}
],{
'allowDiskUse': true,});
如果您想要每个阶段的完整解释和逻辑,请告诉我。