MongoDB는 한 번에 여러 컬렉션 쿼리
users
{
"_id":"12345",
"admin":1
},
{
"_id":"123456789",
"admin":0
}
posts
{
"content":"Some content",
"owner_id":"12345",
"via":"facebook"
},
{
"content":"Some other content",
"owner_id":"123456789",
"via":"facebook"
}
다음은 내 mongodb의 샘플입니다. "페이스 북"과 같은 "경유"속성이 있고 관리자 ( "관리자": 1)에 의해 게시 된 모든 게시물을 얻고 싶습니다. 이 쿼리를 얻는 방법을 알 수 없습니다. mongodb는 관계형 데이터베이스가 아니기 때문에 조인 작업을 할 수 없습니다. 해결책은 무엇일까요?
MongoDB에서 JOIN을 시도하면 MongoDB 사용 목적이 무효화됩니다. 그러나 DBref를 사용하고 이러한 참조를 자동으로 가져 오도록 애플리케이션 수준 코드 (또는 라이브러리)를 작성할 수 있습니다.
또는 스키마를 변경하고 포함 된 문서를 사용할 수 있습니다 .
최종 선택은 현재 상태 그대로두고 두 가지 쿼리를 수행하는 것입니다.
귀하의 질문에 대한 답변입니다.
db.getCollection('users').aggregate([
{$match : {admin : 1}},
{$lookup: {from: "posts",localField: "_id",foreignField: "owner_id",as: "posts"}},
{$project : {
posts : { $filter : {input : "$posts" , as : "post", cond : { $eq : ['$$post.via' , 'facebook'] } } },
admin : 1
}}
])
또는 mongodb 그룹 옵션을 사용할 수 있습니다.
db.getCollection('users').aggregate([
{$match : {admin : 1}},
{$lookup: {from: "posts",localField: "_id",foreignField: "owner_id",as: "posts"}},
{$unwind : "$posts"},
{$match : {"posts.via":"facebook"}},
{ $group : {
_id : "$_id",
posts : {$push : "$posts"}
}}
])
$lookup
(multiple)을 사용 하여 여러 컬렉션에서 레코드를 가져올 수 있습니다 .
예:
더 많은 컬렉션이있는 경우 (여기 데모 용 컬렉션이 3 개 있습니다. 3 개 이상있을 수 있습니다). 단일 개체의 3 개 컬렉션에서 데이터를 가져오고 싶습니다.
컬렉션은 다음과 같습니다.
db.doc1.find (). pretty ();
{
"_id" : ObjectId("5901a4c63541b7d5d3293766"),
"firstName" : "shubham",
"lastName" : "verma"
}
db.doc2.find (). pretty ();
{
"_id" : ObjectId("5901a5f83541b7d5d3293768"),
"userId" : ObjectId("5901a4c63541b7d5d3293766"),
"address" : "Gurgaon",
"mob" : "9876543211"
}
db.doc3.find (). pretty ();
{
"_id" : ObjectId("5901b0f6d318b072ceea44fb"),
"userId" : ObjectId("5901a4c63541b7d5d3293766"),
"fbURLs" : "http://www.facebook.com",
"twitterURLs" : "http://www.twitter.com"
}
이제 쿼리는 다음과 같습니다.
db.doc1.aggregate([
{ $match: { _id: ObjectId("5901a4c63541b7d5d3293766") } },
{
$lookup:
{
from: "doc2",
localField: "_id",
foreignField: "userId",
as: "address"
}
},
{
$unwind: "$address"
},
{
$project: {
__v: 0,
"address.__v": 0,
"address._id": 0,
"address.userId": 0,
"address.mob": 0
}
},
{
$lookup:
{
from: "doc3",
localField: "_id",
foreignField: "userId",
as: "social"
}
},
{
$unwind: "$social"
},
{
$project: {
__v: 0,
"social.__v": 0,
"social._id": 0,
"social.userId": 0
}
}
]).pretty();
그러면 결과는 다음과 같습니다.
{
"_id" : ObjectId("5901a4c63541b7d5d3293766"),
"firstName" : "shubham",
"lastName" : "verma",
"address" : {
"address" : "Gurgaon"
},
"social" : {
"fbURLs" : "http://www.facebook.com",
"twitterURLs" : "http://www.twitter.com"
}
}
각 컬렉션의 모든 레코드를 원하는 경우 쿼리에서 아래 줄을 제거해야합니다.
{
$project: {
__v: 0,
"address.__v": 0,
"address._id": 0,
"address.userId": 0,
"address.mob": 0
}
}
{
$project: {
"social.__v": 0,
"social._id": 0,
"social.userId": 0
}
}
위의 코드를 제거한 후 총 레코드를 다음과 같이 얻습니다.
{
"_id" : ObjectId("5901a4c63541b7d5d3293766"),
"firstName" : "shubham",
"lastName" : "verma",
"address" : {
"_id" : ObjectId("5901a5f83541b7d5d3293768"),
"userId" : ObjectId("5901a4c63541b7d5d3293766"),
"address" : "Gurgaon",
"mob" : "9876543211"
},
"social" : {
"_id" : ObjectId("5901b0f6d318b072ceea44fb"),
"userId" : ObjectId("5901a4c63541b7d5d3293766"),
"fbURLs" : "http://www.facebook.com",
"twitterURLs" : "http://www.twitter.com"
}
}
이전에 MongoDB에서 언급했듯이 컬렉션간에 조인 할 수 없습니다.
예를 들어 솔루션은 다음과 같습니다.
var myCursor = db.users.find({admin:1});
var user_id = myCursor.hasNext() ? myCursor.next() : null;
db.posts.find({owner_id : user_id._id});
참조 매뉴얼-커서 섹션 참조 : http://es.docs.mongodb.org/manual/core/cursors/
Other solution would be to embed users in posts collection, but I think for most web applications users collection need to be independent for security reasons. Users collection might have Roles, permissons, etc.
posts
{
"content":"Some content",
"user":{"_id":"12345", "admin":1},
"via":"facebook"
},
{
"content":"Some other content",
"user":{"_id":"123456789", "admin":0},
"via":"facebook"
}
and then:
db.posts.find({user.admin: 1 });
Perform multiple queries or use embedded documents or look at "database references".
One solution: add isAdmin: 0/1 flag to your post collection document.
Other solution: use DBrefs
You can write a sample JavaScript as below and call the function when required.
Do refer the illustration at : http://dbversity.com/mongodb-querying-multiple-collections-with-a-javascript/
function colListQuery() {
var tcol = new Array()
tcol= db.getCollectionNames();
for(var i = 1; i < tcol.length ; i++) {
query = “db.” + tcol[i] + “.find()”;
var docs= eval(query);
docs.forEach( function(doc, index){ print( “Database_Name:”, db, “Collection_Name:”, tcol[i], “x_value:”, doc.x, “_id:”, doc._id) });
}
}
Then call it with colListQuery() when you require it as shown in the illustaration.
참고URL : https://stackoverflow.com/questions/6502541/mongodb-query-multiple-collections-at-once
'Program Tip' 카테고리의 다른 글
C #에서 SHA1 알고리즘을 사용한 해싱 (0) | 2020.11.22 |
---|---|
Android Studio-XML 편집기 자동 완성이 지원 라이브러리에서 작동하지 않음 (0) | 2020.11.22 |
zeromq : 무한 대기를 방지하는 방법? (0) | 2020.11.21 |
setup.py에서 라이브러리 버전을 어떻게 지정할 수 있습니까? (0) | 2020.11.21 |
SELECT * FROM 여러 테이블. (0) | 2020.11.21 |