Jak dołączyć do zapytania w mongodb?
Mam taką kolekcję dokumentów użytkownika:
User {
id:"001"
name:"John",
age:30,
friends:["userId1","userId2","userId3"....]
}
Użytkownik ma wielu znajomych, mam następujące zapytanie w SQL:
select * from user where in (select friends from user where id=?) order by age
Chciałbym mieć coś podobnego w MongoDB. 10 answers
Edit: ta odpowiedź dotyczy tylko wersji MongoDb przed v3. 2.
Nie możesz zrobić tego, co chcesz w jednym zapytaniu. Najpierw należy pobrać listę identyfikatorów znajomych, a następnie przekazać je do drugiego zapytania, aby pobrać dokumenty i posortować je według wieku.
var user = db.user.findOne({"id" : "001"}, {"friends": 1})
db.user.find( {"id" : {$in : user.friends }}).sort("age" : 1);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-30 17:59:28
Aby mieć wszystko za pomocą jednego zapytania używając funkcji $ lookup frameworku agregacji, spróbuj tego :
db.User.aggregate(
[
// First step is to extract the "friends" field to work with the values
{
$unwind: "$friends"
},
// Lookup all the linked friends from the User collection
{
$lookup:
{
from: "User",
localField: "friends",
foreignField: "_id",
as: "friendsData"
}
},
// Sort the results by age
{
$sort: { 'friendsData.age': 1 }
},
// Get the results into a single array
{
$unwind: "$friendsData"
},
// Group the friends by user id
{
$group:
{
_id: "$_id",
friends: { $push: "$friends" },
friendsData: { $push: "$friendsData" }
}
}
]
)
Załóżmy, że zawartość twojej kolekcji użytkowników jest następująca:
{
"_id" : ObjectId("573b09e6322304d5e7c6256e"),
"name" : "John",
"age" : 30,
"friends" : [
"userId1",
"userId2",
"userId3"
]
}
{ "_id" : "userId1", "name" : "Derek", "age" : 34 }
{ "_id" : "userId2", "name" : "Homer", "age" : 44 }
{ "_id" : "userId3", "name" : "Bobby", "age" : 12 }
Wynik zapytania będzie następujący:
{
"_id" : ObjectId("573b09e6322304d5e7c6256e"),
"friends" : [
"userId3",
"userId1",
"userId2"
],
"friendsData" : [
{
"_id" : "userId3",
"name" : "Bobby",
"age" : 12
},
{
"_id" : "userId1",
"name" : "Derek",
"age" : 34
},
{
"_id" : "userId2",
"name" : "Homer",
"age" : 44
}
]
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-17 12:59:17
Https://docs.mongodb.org/manual/reference/operator/aggregation/lookup/
To jest dokument dla zapytania join w mongodb , jest to nowa funkcja od wersji 3.2.
Więc to będzie pomocne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-25 19:04:38
MongoDB nie ma joinów, ale w Twoim przypadku możesz to zrobić:
db.coll.find({friends: userId}).sort({age: -1})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-30 14:46:09
Możesz używać w Moongoose JS .populate()
i { populate : { path : 'field' } }
.
Przykład:
Modele:
mongoose.model('users', new Schema({
name:String,
status: true,
friends: [{type: Schema.Types.ObjectId, ref:'users'}],
posts: [{type: Schema.Types.ObjectId, ref:'posts'}],
}));
mongoose.model('posts', new Schema({
description: String,
comments: [{type: Schema.Types.ObjectId, ref:'comments'}],
}));
mongoose.model('comments', new Schema({
comment:String,
status: true
}));
Jeśli chcesz zobaczyć posty swoich znajomych, możesz użyć tego.
Users.find(). //Collection 1
populate({path:'friends', //Collection 2
populate:{path:'posts' //Collection 3
}})
.exec();
Jeśli chcesz zobaczyć posty swoich znajomych, a także przynieść wszystkie komentarze, możesz użyć tego i też, możesz zidentyfikować kolekcję, jeśli nie znajdziesz I zapytanie jest błędne.
Users.find(). //Collection 1
populate({path:'friends', //Collection 2
populate:{path:'posts', //Collection 3
populate:{path:'commets, model:Collection'//Collection 4 and more
}}})
.exec();
I na koniec, jeśli chcesz uzyskać tylko niektóre pola z jakiejś kolekcji, możesz użyć propiertie select Example:
Users.find().
populate({path:'friends', select:'name status friends'
populate:{path:'comments'
}})
.exec();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-27 06:44:54
Jednym z rodzajów dołączania do zapytania w mongoDB jest zapytanie w jednej kolekcji o id , które pasują, umieszczanie ID na liście (idlist) i znajdowanie w innej (lub tej samej) kolekcji za pomocą $in : idlist
u = db.friends.find({"friends": ? }).toArray()
idlist= []
u.forEach(function(myDoc) { idlist.push(myDoc.id ); } )
db.friends.find({"id": {$in : idlist} } )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-20 03:55:28
/ Align = "left" /
User.findOne({ _id: "userId"})
.populate('friends')
.exec((err, user) => {
//do something
});
Wynik jest taki sam:
{
"_id" : "userId",
"name" : "John",
"age" : 30,
"friends" : [
{ "_id" : "userId1", "name" : "Derek", "age" : 34 }
{ "_id" : "userId2", "name" : "Homer", "age" : 44 }
{ "_id" : "userId3", "name" : "Bobby", "age" : 12 }
]
}
To samo: Mongoose - za pomocą wypełnienia na tablicy ObjectId
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-23 19:56:31
Możesz użyć playOrm, aby zrobić to, co chcesz w jednym zapytaniu (z S-SQL skalowalny SQL).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-07 17:31:48
var p = db.sample1.find().limit(2) ,
h = [];
for (var i = 0; i < p.length(); i++)
{
h.push(p[i]['name']);
}
db.sample2.find( { 'doc_name': { $in : h } } );
U mnie działa.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-28 07:52:27
Możesz to zrobić za jednym razem używając mongo-join-query
. Oto jak by to wyglądało:
const joinQuery = require("mongo-join-query");
joinQuery(
mongoose.models.User,
{
find: {},
populate: ["friends"],
sort: { age: 1 },
},
(err, res) => (err ? console.log("Error:", err) : console.log("Success:", res.results))
);
Wynik spowoduje uporządkowanie użytkowników według wieku i osadzenie wszystkich obiektów znajomych.
Jak to działa?Behind the scenes mongo-join-query
użyje schematu Mongoose do określenia, które modele należy połączyć i utworzy rurociąg agregacji, który wykona połączenie i zapytanie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-13 14:36:55