次のようなユーザードキュメントコレクションがあります。
User {
id:"001"
name:"John",
age:30,
friends:["userId1","userId2","userId3"....]
}
ユーザーには多くの友人がいます。SQLには次のクエリがあります。
select * from user where in (select friends from user where id=?) order by age
MongoDBでも同様のものが欲しいです。
編集:この回答は、v3.2より前のMongoDbのバージョンにのみ適用されます。
1つのクエリだけで目的の操作を行うことはできません。最初に友人のユーザーIDのリストを取得し、次にそれらのIDを2番目のクエリに渡してドキュメントを取得し、年齢で並べ替える必要があります。
var user = db.user.findOne({"id" : "001"}, {"friends": 1})
db.user.find( {"id" : {$in : user.friends }}).sort("age" : 1);
集約フレームワークの$ lookup機能を使用して、すべてを1つのクエリで実行するには、次を試してください。
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" }
}
}
]
)
Userコレクションのコンテンツは次のとおりだとしましょう:
{
"_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 }
クエリの結果は次のようになります。
{
"_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
}
]
}
https://docs.mongodb.org/manual/reference/operator/aggregation/lookup/
これはmongodbの結合クエリのドキュメントです。これはバージョン3.2の新機能です。
したがって、これは役に立ちます。
MongoDBには結合はありませんが、あなたの場合は次のことができます:
db.coll.find({friends: userId}).sort({age: -1})
mongoDBのクエリに参加する1つの種類は、1つのコレクションで一致するIDを要求し、IDをリスト(idlist)に入れ、他の(または同じ)コレクションで$ in:idlistを使用して検索します
u = db.friends.find({"friends": ? }).toArray()
idlist= []
u.forEach(function(myDoc) { idlist.Push(myDoc.id ); } )
db.friends.find({"id": {$in : idlist} } )
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 } } );
わたしにはできる。
mongo-join-query
。これは次のようになります。
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))
);
結果には、ユーザーが年齢順に並べられ、すべての友達オブジェクトが埋め込まれます。
舞台裏mongo-join-query
は、Mongooseスキーマを使用して、結合するモデルを決定し、結合とクエリを実行する 集約パイプライン を作成します。
アレイフレンドのみを設定します。
User.findOne({ _id: "userId"})
.populate('friends')
.exec((err, user) => {
//do something
});
結果は次のように同じです。
{
"_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 }
]
}
PlayOrmを使用して、1つのクエリ(S-SQLスケーラブルSQL)で必要なことを実行できます。