Google AdSense (text)

hidden logo stop

Moving

거지 같은 이글루스 광고노출 정책이 싫어서,
새 보금자리(http://blog.leocat.kr/)로 이사감.

[MongoDB] find할 때 array length 조건 Computer & Program

MongoDB는 사용할 때 간혹 제약이 많이 느껴진다. RDB에 너무 익숙해져서 생각 자체가 RDB에 굳어진듯.. 그 중 하나가 document에 있는 배열 field가 특정 개수 이상인 경우를 찾는 것이다.

예를 들어, 핸드폰 주소록을 만들 때 1명의 연락처를 1개의 document에 넣고, 전화번호를 배열로 넣는 경우이다. 아래의 예는 3명의 사용자 u1, u2, u3가 있다. 이 중 전화번호가 3개 이상인 사용자를 찾고 싶다. 어떻게 할까..??

$ mongo
> use phonebook;
> db.phonebook.insert({'name':'u1', 'phone':[{'home':'02-1234-5678'}, {'mobile':'010-1234-5678'}]});
> db.phonebook.insert({'name':'u2', 'phone':[{'home':'02-1234-5678'}, {'mobile':'010-1234-5678'}, {'office':'064-1234-5678'}]});
> db.phonebook.insert({'name':'u3', 'phone':[{'mobile':'010-1234-5678'}]});
> db.phonebook.count();3
>

방법은 아주 간단하다. $where 연산자를 사용하면 된다.
> db.phonebook.findOne({$where:'this.phone.length>=3'});
{
    "_id" : ObjectId("50d6aa1cc5380ffd18a97b7b"),
    "name" : "u2",
    "phone" : [
        {
            "home" : "02-1234-5678"
        },
        {
            "mobile" : "010-1234-5678"
        },
        {
            "office" : "064-1234-5678"
        }
    ]
}


$where 연산자javascript 관련 연산자이며, 각 document가 조건을 만족하는지 체크하게 된다. 여기서 중요한 점이 있는데, 모든 document를 체크하기 때문에 index를 타지 못 해서 속도가 현저히 느릴 수 있다.그리고 javascript를 그대로 사용하기 때문에 아래처럼 javascript 함수를 쓸 수도 있다.
> db.phonebook.findOne({$where:function() {return this.phone.length>=3}});

하지만 다시 얘기하지만.. 느리다.. 때문에 이런 경우가 자주 발생한다면 별도의 field를 생성해서 배열 개수를 저장하는 것이 좋다고들 얘기한다.

> db.phonebook.ensureIndex({phoneCount:1});
> db.phonebook.findOne({'phoneCount':{$gte:3}});
{
    "_id" : ObjectId("50d6aa1cc5380ffd18a97b7b"),
    "name" : "u2",
    "phone" : [
        {
            "home" : "02-1234-5678"
        },
        {
            "mobile" : "010-1234-5678"
        },
        {
            "office" : "064-1234-5678"
        }
    ],
    "phoneCount" : 3
}



- 참고
In Mongo DB, how do I find documents where array size is greater than 1
Operation Reference - MongoDB Manual :: $where

덧글

댓글 입력 영역

Google AdSense (text/image)