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
}
]
我是 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
}
]