MongoDB 使用两个集合的查询

MongoDB Query that uses two collection

我是 MongoDB 的新手,我被困在编写查询的任务中。 我的问题陈述是我有两个集合

maening userId1=>follows userId2
+---------+---------+
| userId1 | userId2 |
+---------+---------+
| 1       | 2       |
+---------+---------+
| 1       | 3       |
+---------+---------+
| 1       | 4       |
+---------+---------+
| 2       | 3       |
+---------+---------+
| 3       | 1       |
+---------+---------+
second table is as follows
+---------+--------+----------------+
| tweetId | userId | tweetText      |
+---------+--------+----------------+
| ****    | 1      | Tweet By user1 |
+---------+--------+----------------+
| ****    | 2      | Tweet By user2 |
+---------+--------+----------------+
| ****    | 3      | Tweet By user3 |
+---------+--------+----------------+
| ****    | 4      | Tweet By user4 |
+---------+--------+----------------+

我希望我的结果包含 user1 关注的用户的所有推文...?????

您可以使用聚合来实现您的特定结果。 就像你有 2 个集合,first_collection 和 second_colleciton。

db.getCollection('first_collecition').aggregate([
{
        "$facet":{
            "tweets":[
                "$lookup":{
                    "from":"second_collection",
                    "localField":"userId1",
                    "foreignField":"userId",
                    "as":"tweets"
                },
                {
                    "$project":{
                        "userId":"$userId",
                        "tweets":"tweetText"
                    }
                }
            ]
        }
    }

])

您需要像这样设计您的用户和推文模式:

用户:

const mongoose = require("mongoose");

const userSchema = new mongoose.Schema({
  username: String,
  follows: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User"
    }
  ]
});

module.exports = mongoose.model("User", userSchema);

推文:

const mongoose = require("mongoose");

const tweetSchema = new mongoose.Schema({
  userId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User"
  },
  tweetText: String
});

module.exports = mongoose.model("Tweet", tweetSchema);

然后你可以使用下面的代码,插入用户,推文,获取用户和他的关注者,以及用户的关注者的推文:

Index.js

const express = require("express");
const app = express();
const mongoose = require("mongoose");
const url = "mongodb://localhost:27017/tweet"; //change url to your db
const User = require("./models/user");
const Tweet = require("./models/tweet");

const port = 3000;

app.use(express.json());

mongoose
  .connect(url, {
    useNewUrlParser: true,
    useUnifiedTopology: true
  })
  .then(() => {
    app.listen(port, () => {
      console.log(`App running on port ${port}...`);
    });
  })
  .catch(error => console.log(error));

app.post("/user", async (req, res) => {
  let result = await User.create(req.body);
  res.send(result);
});

app.get("/user/:userId", async (req, res) => {
  const result = await User.findById(req.params.userId).populate({
    path: "follows",
    select: "_id username"
  });
  res.send(result);
});

app.post("/user/:userId/follow/:followedUserId", async (req, res) => {
  const result = await User.findByIdAndUpdate(
    req.params.userId,
    {
      $push: {
        follows: req.params.followedUserId
      }
    },
    { new: true }
  );
  res.send(result);
});

app.post("/tweet", async (req, res) => {
  let result = await Tweet.create(req.body);
  res.send(result);
});

app.get("/user/:userId/followedTweets", async (req, res) => {
  const user = await User.findById(req.params.userId);

  const result = await Tweet.find({ userId: { $in: user.follows } });
  res.send(result);
});

首先创建几个用户发送 POST 到这个 url http://localhost:3000/user:

要求:

{
    "username": "username1"
}

然后使用此 url:

向给定用户添加关注者

http://localhost:3000/user/5ddfdfaf8c62b141146cbcff/follow/5ddfdfd18c62b141146cbd02

这意味着 ID 为 5ddfdfaf8c62b141146cbcff 的用户关注用户 5ddfdfd18c62b141146cbd02

此时你可以得到一个用户和他关注的用户发送一个 GET 请求到这个 url:

http://localhost:3000/user/5ddfdfaf8c62b141146cbcff

响应将是这样的:

{
    "follows": [
        {
            "_id": "5ddfdfbf8c62b141146cbd00",
            "username": "username2"
        },
        {
            "_id": "5ddfdfc78c62b141146cbd01",
            "username": "username3"
        },
        {
            "_id": "5ddfdfd18c62b141146cbd02",
            "username": "username4"
        }
    ],
    "_id": "5ddfdfaf8c62b141146cbcff",
    "username": "username1",
    "__v": 0
}

从这个回复中,我们了解到用户名 1 跟在用户名 2、用户名 3 和用户名 4 之后。

然后你可以创建发送 POST 到这个 url 的推文:http://localhost:3000/tweet

要求:

{
    "userId": "5ddfdfbf8c62b141146cbd00",
    "tweetText": "user 2 tweet 1"
}

响应:

{
    "_id": "5ddfe1e7911cec475093f623",
    "userId": "5ddfdfbf8c62b141146cbd00",
    "tweetText": "user 2 tweet 1",
    "__v": 0
}

添加几条这样的推文后,您可以发送 GET 请求此 url 以获取用户关注的用户的推文:

http://localhost:3000/user/5ddfdfaf8c62b141146cbcff/followedTweets

响应将是这样的:

[
    {
        "_id": "5ddfe1e7911cec475093f623",
        "userId": "5ddfdfbf8c62b141146cbd00",
        "tweetText": "user 2 tweet 1",
        "__v": 0
    },
    {
        "_id": "5ddfe20a911cec475093f624",
        "userId": "5ddfdfbf8c62b141146cbd00",
        "tweetText": "user 2 tweet 2",
        "__v": 0
    },
    {
        "_id": "5ddfe22b911cec475093f625",
        "userId": "5ddfdfc78c62b141146cbd01",
        "tweetText": "user 3 tweet 1",
        "__v": 0
    }
]