Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB에서 객체 배열 내 여러 일치 항목을 찾는 쿼리 작성 방법

MongoDB에서 객체 배열 안에 포함된 여러 조건에 일치하는 문서를 찾으려면 $and 연산자와 $regex 연산자를 함께 사용하면 됩니다. $and는 하나 이상의 표현식 배열에 대해 논리 AND 연산을 수행하며, 배열 내 모든 조건을 만족하는 문서만 선택합니다. 또한 배열 요소를 조건별로 검사할 때는 $elemMatch를 활용합니다.

샘플 컬렉션 생성하기

먼저 문서가 담긴 컬렉션을 생성해 보겠습니다.

> db.demo525.insertOne({"details":[{Name:"Chris","CountryName":"US"}]});{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e8ae5ef437efc8605595b66")
}
> db.demo525.insertOne({"details":[{Name:"Bob","CountryName":"UK"}]});{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e8ae5f8437efc8605595b67")
}
> db.demo525.insertOne({"details":[{Name:"chris","CountryName":"us"}]});{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e8ae602437efc8605595b68")
}
> db.demo525.insertOne({"details":[{Name:"Mike","CountryName":"UK"}]});{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e8ae60b437efc8605595b69")
}

위 예제에서는 대소문자가 다른 값들(예: "Chris"와 "chris", "US"와 "us")을 의도적으로 포함했습니다. 이후 정규식의 'i' 옵션으로 대소문자를 구분하지 않고 검색할 수 있음을 확인하기 위함입니다.

find() 메서드로 전체 문서 조회하기

find() 메서드를 사용해 컬렉션의 모든 문서를 출력해 보겠습니다.

> db.demo525.find();

실행 결과는 다음과 같습니다.

{ "_id" : ObjectId("5e8ae5ef437efc8605595b66"), "details" : [ { "Name" : "Chris", "CountryName" : "US" } ] }
{ "_id" : ObjectId("5e8ae5f8437efc8605595b67"), "details" : [ { "Name" : "Bob", "CountryName": "UK" } ] }
{ "_id" : ObjectId("5e8ae602437efc8605595b68"), "details" : [ { "Name" : "chris", "CountryName" : "us" } ] }
{ "_id" : ObjectId("5e8ae60b437efc8605595b69"), "details" : [ { "Name" : "Mike", "CountryName" : "UK" } ] }

객체 배열에서 여러 조건으로 일치 항목 찾기

다음은 객체 배열 내에서 Name이 "Chris"로 시작하고 CountryName이 "us"로 시작하는 문서를 찾는 쿼리입니다. 각 조건은 $elemMatch로 배열 요소를 검사하고, 두 조건은 $and로 결합됩니다.

> db.demo525.find(
... {"$and": [
...     { "details" : { "$elemMatch" :{ "Name": {$regex: new RegExp('^' + 'Chris', 'i')}}} },
...     { "details" : { "$elemMatch" :{ "CountryName": {$regex: new RegExp('^' + 'us', 'i')}}}
}
... ]}
... )

실행 결과는 다음과 같습니다.

{ "_id" : ObjectId("5e8ae5ef437efc8605595b66"), "details" : [ { "Name" : "Chris", "CountryName" : "US" } ] }
{ "_id" : ObjectId("5e8ae602437efc8605595b68"), "details" : [ { "Name" : "chris", "CountryName" : "us" } ] }

결과 분석

쿼리 결과에서 확인할 수 있듯이, Name이 "Chris"(대소문자 무관)로 시작하고 동시에 CountryName이 "us"(대소문자 무관)로 시작하는 두 개의 문서만 반환되었습니다. 정규식 옵션 'i'(case-insensitive) 덕분에 "Chris/US"와 "chris/us"처럼 대소문자가 달라도 모두 매칭되었습니다. 반면 "Bob/UK"나 "Mike/UK" 문서는 두 조건 중 하나라도 만족하지 않아 결과에서 제외되었습니다.

이처럼 $and와 $elemMatch, 그리고 $regex를 조합하면 객체 배열 내부의 여러 필드에 대해 복잡한 조건 검색을 손쉽게 수행할 수 있습니다.