2012-08-10 5 views
2

에서 같은 필드에 여러 문서에 조건을 적용 나는 다음과 같은 구조의 문서가 :MongoDB를

user {id: 123, tag:"tag1"} 
user {id: 123, tag:"tag2"} 
user {id: 123, tag:"tag3"} 
user {id: 456, tag:"tag1"} 

나는이 사용자가 3 개 태그 (AND 연산)으로 기록이 있는지 찾으려면 감안할 때 사용자 ID . 사용자가 "이 tag1"AND "TAG2"AND "TAG3"에 대한 기록을 다음과 같이 될 것이다 진정한

SQL 동등한를 반환 할 경우 :

SELECT * FROM users WHERE 
    EXISTS (SELECT * FROM tags WHERE user_id = users.id AND name ='tag1') AND 
    EXISTS (SELECT * FROM tags WHERE user_id = users.id AND name ='tag2') AND 
    user_id=123 

가 어떻게하여 MongoDB에서 시뮬 무언가를 표현할 수 있습니까?

+0

얼마나 빨리 이러한 쿼리를해야합니까? 집계 프레임 워크를 사용하여 ID별로 태그를 그룹화 한 다음 원하는 조건과 일치시킬 수 있습니다. –

답변

4

MongoDB에는 조인 개념이 없으므로 입력 내용을 단일 문서로 축소하여 작업해야합니다. 당신은, 태그의 배열을 저장되도록

다음과 같은 문서 구조를 변경하는 경우 :

{id: 123, tag:["tag1","tag2","tag3"]} 
{id: 456, tag:["tag1"]} 

당신은 다음과 같이 쿼리를 수행 할 수 있습니다

db.user.find({$and:[{tag:"tag1"},{tag:"tag2"},{tag:"tag3"}]}) 

필요한 경우, 당신은 mapid를 써서 userid에 대한 태그의 배열을 출력 할 수있다. 위의 질의를 할 수있다.

편집 - 포함 간단한지도-감소 여기

입니다 정말 간단한 맵 줄이기 위의 find 쿼리에 대한 유용한 포맷으로 초기 입력을받을 수 있습니다.

var map = function() {emit(this.id, {tag:[this.tag]});} 
var reduce = function(key, values){ 
    var result_array=[]; 
    values.forEach(function(v1){    
     v1.tag.forEach(function(v2){ 
     result_array.push(v2); 
     }); 
    }); 
return {"tag":result_array};} 

var op = db.user.mapReduce(map, reduce, {out:"mr_results"}) 

그럼 당신은 다음과 같이지도-감소 출력 컬렉션 조회 할 수 있습니다

db.mr_results.find({$and:[{"value.tag":"tag1"},{"value.tag":"tag2"}, {"value.tag":"tag3"}]}) 
+0

질문에 대한 답변이 적절하지 않다고 생각합니다. 당신의 접근법과 함께 map/reduce의 예는 그를 더 잘 이해할 수 있습니다. –

+0

@RaviKhakhkhar 간단한지도 - 축소로 업데이트 된 답변 –

+0

감사합니다. upvoted :) –