MongoDbで効率的なクエリを実行して、ユーザーグループにユーザーIDがリストされているすべてのユーザーを検索したいと思います。理想的には、これをMongodbへの単一のリクエストとして作成したいと思います。私が欲しいのはSQLのネストされたselectに対応します。私はこれをmongoシェルで試しました:
db.user.save({_id:"u1", Name:"u1 name"});
db.user.save({_id:"u2", Name:"u1 name"});
db.user.save({_id:"u3", Name:"u3 name"});
db.usergroup.save({_id:"g1", Users: ["u2","u3"]});
これが私がやりたい選択ですが、["u2"、 "u3"]配列をハードコーディングせずに:
db.user.find({_id:{$in:["u2","u3"]}}).forEach(printjson);
これは正常に機能し、u2とu3のユーザーオブジェクトを返します。
ここで問題となるのは、クエリで抽出された$ in演算子のユーザーIDの配列を取得して、クエリ全体を1回のリクエストで実行できるようにする方法です。
このような「ネストされたクエリ」は機能しません。
db.user.find({_id:{$in:db.usergroup.find({_id:"g1"},{_id:0,Users:1})}}).forEach(printjson);
このエラーが発生します:Tue Mar 27 06:17:41キャッチされない例外:エラー:{"$ err": "invalid query"、 "code":12580}の読み込みに失敗しました:mongoNestedSelect.js
1)これはmongodbで可能ですか?
2)公式のc#ドライバーでこれを行う方法は?
MongoDBでのこのような質問に対する答えは、多くの場合、データを非正規化することです。グループ内のユーザーのリストだけが必要な場合は、ユーザーID andユーザー名をグループドキュメントに保存できます。いくつかの方法では、データベースを正規化された形式に配置しようとするのではなく、画面に表示したい結果に従ってデータベースを構造化します。
明らかに、これは(名前付きの)ユーザーグループリストが単一のドキュメントに収まる場合にのみ機能しますが、現在のアプローチには、グループの最大サイズに関してもいくつかの制限があります。
別のアプローチは、ユーザーが属するグループを各「ユーザー」ドキュメントの配列に格納することです。その配列フィールドにインデックスを追加すると、グループごとにユーザーを見つけることができます。ユーザーがグループ内のメンバーよりも少ないグループに属する可能性が高いことを考えると、これがここでの最良のアプローチである可能性があります。
db.user.save({_id:"u1", name:"u1 name", groups:[{_id:"g1", name:"Group One"}, ...]});
ここでも、グループ名を_idとともに保存して、ユーザーが属するグループのリストを1回の往復ですぐに表示できるようにすることができます。もちろん、グループ名の変更を許可する場合は、バックグラウンドタスクを開始して、名前のこれらすべてのコピーを修正する必要があります。
また、独自のMongoDB IDジェネレーターではなく、組み込みのMongoDB IDジェネレーターを使用します。これには、多くの望ましいプロパティがあります。
関数の定義
function bbb(){
var org_ids = new Array();
var orgs =
db.orgTreeNode.find({ancestors:"ca5cd344-ba47-4601-a07b-ea2c684bfb4e"},{"_id":1});
orgs.forEach(function(org){
org_ids.Push(org._id);
})
return db.user.find({"org":{$in:org_ids}}).skip(300).limit(10);
}
実行機能
bbb()
それがあなたに答えを得るきっかけになることができれば-
db.users.find({
_id: {
$in: db.logs.find({
loggedbyuser: {
$ne: ObjectId("569f9d093447ee781ca80b52")
},
logtype: "marketfetched",
"logcreated": {
$gt: new ISODate("2016-02-06T00:00:00.871Z")
}
}, {
loggedbyuser: 1,
_id: 0
}).sort({
'logcreated': -1
}).map(function(like) {
return like.loggedbyuser;
})
}
}).map(function(like) {
return like.fullname;
});
-sUReN
SQLクエリ:(グループ化と個別のカウント)
select city,count(distinct(emailId)) from TransactionDetails group by city;
同等のmongoクエリは次のようになります:
db.TransactionDetails.aggregate([
{$group:{_id:{"CITY" : "$cityName"},uniqueCount: {$addToSet: "$emailId"}}},
{$project:{"CITY":1,uniqueCustomerCount:{$size:"$uniqueCount"}} }
]);
私はmongodbのネストされたクエリについて同じことを考えていました。私の場合、私は少しパッツしてそれを機能させました、そしてあなたも「$ or」を使用してtoArray()を使用することでそうなると思います
db.user.find({$or:db.usergroup.find({_id:"g1"},{_id:0,Users:1}).toArray()})
正しくないかもしれませんが、これは次のクエリを使用して機能した私のデータの例です。この場合、IDを別のクエリにフィードバックする理由としては明らかに少しばかげていますが、それが機能するかどうかを確認したいと思っていました。
db.notification.find({$or:db.notification.find({'startDate': { '$gte': ISODate("2019-08-01") }},{_id:1}).limit(10).toArray()})