你好,朋友,我有一个关于在MongoDB中加入多个集合的问题 我的集合架构如下所示

Posts Collection
{
    "type": "POST_TYPE",    
    "_id": "63241dffb0f6770c23663230",
    "user_id": "63241dffb0f6770c23663230",
    "post_id": "63241dffb0f6770c23663230",
    "likes": 50
}
Post Types: 1. Event
{
    "date": "2022-09-16T07:07:18.242+00:00",    
    "_id": "63241dffb0f6770c23663230",
    "user_id": "63241dffb0f6770c23663230",
    "venue": "Some Place",
    "lat": "null",
    "long": "null",
}
Post Types: 2. Poll
{
    "created_date": "2022-09-16T07:07:18.242+00:00",    
    "_id": "63241dffb0f6770c23663230",
    "user_id": "63241dffb0f6770c23663230",
    "question": "Question??????",
    "poll_opt1": "Yes",
    "poll_opt2": "No",
    "poll_opt1_count": "5",
    "poll_opt2_count": "2"
}

现在我必须加入邮政收集与各自的收集.

"post_id" to Event::_id or Poll::_id with condition to Post::type

我try 过聚合,但它没有给出预期的输出. 我正在try 获得如下所示的输出

[
  {
    "type": "event",
    "_id": "63241dffb0f6770c23663230",
    "user_id": "63241dffb0f6770c23663230",
    "post_id": {
      "date": "2022-09-16T07:07:18.242+00:00",
      "_id": "63241dffb0f6770c23663230",
      "user_id": "63241dffb0f6770c23663230",
      "venue": "Some Place",
      "lat": "null",
      "long": "null"
    },
    "likes": 50
  },
  {
    "type": "poll",
    "_id": "63241dffb0f6770c23663230",
    "user_id": "63241dffb0f6770c23663230",
    "post_id": {
      "created_date": "2022-09-16T07:07:18.242+00:00",
      "_id": "63241dffb0f6770c23663230",
      "user_id": "63241dffb0f6770c23663230",
      "question": "Question??????",
      "poll_opt1": "Yes",
      "poll_opt2": "No",
      "poll_opt1_count": "5",
      "poll_opt2_count": "2"
    },
    "likes": 50
  }
]

有没有什么有效的方法来实现这一点,或者更好的MongoDB模式来管理这些类型的记录?

推荐答案

您可以try 这样的操作,使用$facet:

db.posts.aggregate([
  {
    "$facet": {
      "eventPosts": [
        {
          "$match": {
            type: "event"
          },
          
        },
        {
          "$lookup": {
            "from": "events",
            "localField": "post_id",
            "foreignField": "_id",
            "as": "post_id"
          }
        }
      ],
      "pollPosts": [
        {
          "$match": {
            type: "poll"
          },
          
        },
        {
          "$lookup": {
            "from": "poll",
            "localField": "post_id",
            "foreignField": "_id",
            "as": "post_id"
          }
        }
      ]
    }
  },
  {
    "$addFields": {
      "doc": {
        "$concatArrays": [
          "$pollPosts",
          "$eventPosts"
        ]
      }
    }
  },
  {
    "$unwind": "$doc"
  },
  {
    "$replaceRoot": {
      "newRoot": "$doc"
    }
  },
  {
    "$addFields": {
      "post_id": {
        "$cond": {
          "if": {
            "$eq": [
              {
                "$size": "$post_id"
              },
              0
            ]
          },
          "then": {},
          "else": {
            "$arrayElemAt": [
              "$post_id",
              0
            ]
          }
        }
      }
    }
  }
])

在查询中,我们执行以下操作:

  1. $facet内的不同post_type执行二个$lookups.不幸的是,随着post_type的值不同,这一数字将会增加.

  2. 然后我们使用$concatArray将从$facet获得的所有数组组合在一起.

  3. 然后我们展开连接的数组,并使用$replaceRoot将嵌套文档带到根目录.

  4. 最后,对于post_id,我们 Select 第一个数组元素(如果它存在),以匹配所需的输出.

Playground link.

Mongodb相关问答推荐

数组相等条件返回的文档多于与相等匹配的文档:MongoDB

为什么这个查询可以在MongoDB中使用?

MongoDB 按日期时间字段查询 1h 间隔

在 MongoDB 中加入多个集合

如何替换mongodb中的动态键?

在mongoose 中按键查找嵌套对象

System.FormatException occurred in MongoDB.Bson.dll - XXX is not a valid 24 digit hex string

NodeJS + MongoDB:使用 findOne () 从集合中获取数据

如何使用 mongoose 从 MongoDb 获取数据?

MongoDB 文档操作是原子的和隔离的,但它们是否一致?

Springboot 使用 find*() 查询时出现 Mongodb 错误

mongo php副本连接非常慢

django 和 mongodb 是否使迁移成为过go ?

.NET 中的 Mongodb 单元测试

$elemMatch 的 MongoDB 索引

Spring Mongo 条件查询两次相同的字段

在MongoDB中查询一个半​​径内的位置

如何为 node.js 中的 MongoDB 索引指定 javascript 对象中的属性顺序?

通过 Java 执行 Mongo like Query (JSON)

如何使用 mongoose 连接到 mongoDB Atlas