텍스트 검색
개요
텍스트 검색을 사용하면 컬렉션의 string 유형 필드에서 지정된 단어나 구를 검색할 수 있습니다. $text
연산자를 사용하여 텍스트 검색을 수행할 수 있습니다. 이 연산자는 검색 string에서 각 텀을 공백으로 구분하여 논리적 OR
를 수행합니다. 또한 지원되는 언어에 대해 대소문자 구분, 중지 단어, 단어 어간 처리(복수형 또는 기타 시제 등)를 다루는 추가 연산자를 지정할 수도 있습니다. 이는 종종 녹취록, 에세이 또는 웹 페이지와 같은 구조화되지 않은 텍스트에 사용됩니다.
$text
쿼리 연산자를 사용하려면 컬렉션의 텍스트 인덱스에 검색 필드를 지정해야 합니다. 텍스트 인덱스 생성 및 $text
쿼리 연산자 사용에 대한 샘플 코드는 아래 예시를 참조하세요.
참고
Atlas Search를 사용하면 MongoDB 데이터 위에 정확도 기반의 빠른 검색 기능을 구축할 수 있습니다. 지금 바로 완전 관리형 서비스형 데이터베이스인 MongoDB Atlas를 사용해 보세요.
예시
다음 예시는 sample_mflix
데이터베이스에 있는 movies
컬렉션의 샘플 데이터를 사용합니다. title
필드에서 텍스트 검색을 활성화하려면 다음 명령을 사용하여 텍스트 인덱스를 생성하세요.
db.movies.createIndex({ title: "text" });
이 가이드의 예제에서는 단일 필드 텍스트 인덱스를 사용했지만, 텍스트 쿼리를 여러 필드로 확장하는 복합 텍스트 인덱스를 만들 수 있습니다. 다음 명령어는 movies
컬렉션의 두 필드에 텍스트 인덱스를 생성합니다.
db.movies.createIndex({ title: "text", plot: "text" });
팁
텍스트 인덱스에서 필드 가중치 지정
컬렉션당 하나의 텍스트 인덱스만 만들 수 있습니다. 모든 텍스트 검색은 해당 인덱스에 지정된 모든 필드를 쿼리하여 일치하는 항목을 찾습니다.
텍스트 인덱스에 대해 자세히 알아보려면 서버 매뉴얼의 텍스트 인덱스를 참조하세요.
단어 쿼리하기
이 예시에서는 "trek"이라는 단어가 포함된 제목을 검색하여 Star Trek 영화를 쿼리합니다. 여러 단어를 사용하여 쿼리하려면 단어를 공백으로 구분하여 검색어 중 어느 하나라도 일치하는 문서를 조회하도록 합니다 (논리적 OR
).
// Create a query that searches for the string "trek" const query = { $text: { $search: "trek" } }; // Return only the `title` of each matched document const projection = { _id: 0, title: 1, }; // Find documents based on our query and projection const cursor = movies.find(query).project(projection);
이 연산은 다음 문서를 반환합니다.
{ title: 'Trek Nation' } { title: 'Star Trek' } { title: 'Star Trek Into Darkness' } { title: 'Star Trek: Nemesis' } { title: 'Star Trek: Insurrection' } { title: 'Star Trek: Generations' } { title: 'Star Trek: First Contact' } { title: 'Star Trek: The Motion Picture' } { title: 'Star Trek VI: The Undiscovered Country' } { title: 'Star Trek V: The Final Frontier' } { title: 'Star Trek IV: The Voyage Home' } { title: 'Star Trek III: The Search for Spock' } { title: 'Star Trek II: The Wrath of Khan' }
성공! 쿼리를 통해 movies
컬렉션에서 " trek " 라는 단어가 포함된 제목의 모든 문서를 찾았습니다. 안타깝게도 검색에 의도하지 않은 항목이 하나 포함되었습니다. "Trek Nation"은 스타 트렉에 관한 영화이지만 스타 트렉 영화 시리즈의 일부가 아닙니다. 이 문제를 해결하기 위해 좀 더 구체적인 구문을 사용하여 쿼리할 수 있습니다.
구문으로 쿼리하기
쿼리를 보다 구체적으로 작성하려면 "trek" 이라는 단어 대신 "star trek" 이라는 구문을 사용해 보세요. 구문으로 검색하려면 여러 단어로 구성된 구문을 이스케이프 따옴표 (\"<term>\"
)로 묶습니다.
// Create a query that searches for the phrase "star trek" const query = { $text: { $search: "\"star trek\"" } }; // Return only the `title` of each matched document const projection = { _id: 0, title: 1, }; // Find documents based on the query and projection const cursor = movies.find(query).project(projection);
"trek"
이라는 용어 대신 "star trek"
이라는 구문으로 쿼리하면 다음 문서와 일치합니다.
{ title: 'Star Trek' } { title: 'Star Trek Into Darkness' } { title: 'Star Trek: Nemesis' } { title: 'Star Trek: Insurrection' } { title: 'Star Trek: Generations' } { title: 'Star Trek: First Contact' } { title: 'Star Trek: The Motion Picture' } { title: 'Star Trek VI: The Undiscovered Country' } { title: 'Star Trek V: The Final Frontier' } { title: 'Star Trek IV: The Voyage Home' } { title: 'Star Trek III: The Search for Spock' } { title: 'Star Trek II: The Wrath of Khan' }
이 결과에는 데이터베이스에 "star trek"
(이)라는 구문이 포함된 모든 영화가 포함되며, 이 경우 가상의 Star Trek 영화만 표시됩니다. 안타깝게도 이 쿼리는 원래 영화 시리즈의 일부가 아닌 영화 "Star Trek Into
Darkness"
(을)를 반환했습니다. 이 문제를 해결하기 위해 부정을 사용하여 해당 문서를 생략할 수 있습니다.
부정문을 사용한 쿼리
부정 용어를 사용하려면 결과 집합에서 제외하려는 용어 앞에 마이너스 부호 -
를 넣으세요. 이 쿼리 작업은 검색 결과에서 이 용어를 포함하는 모든 문서를 생략합니다. 이 쿼리에는 두 개의 서로 다른 용어가 포함되어 있으므로 그들을 공백으로 구분하세요.
// Create a query that searches for the phrase "star trek" while omitting "into darkness" const query = { $text: { $search: "\"star trek\" -\"into darkness\"" } }; // Include only the `title` field of each matched document const projection = { _id: 0, title: 1, }; // Find documents based on the query and projection const cursor = movies.find(query).project(projection);
부정된 용어로 쿼리하면 다음과 같은 문서가 반환됩니다.
{ title: 'Star Trek' } { title: 'Star Trek: Nemesis' } { title: 'Star Trek: Insurrection' } { title: 'Star Trek: Generations' } { title: 'Star Trek: First Contact' } { title: 'Star Trek: The Motion Picture' } { title: 'Star Trek VI: The Undiscovered Country' } { title: 'Star Trek V: The Final Frontier' } { title: 'Star Trek IV: The Voyage Home' } { title: 'Star Trek III: The Search for Spock' } { title: 'Star Trek II: The Wrath of Khan' }
참고
쿼리 작업은 일치하는 문서가 포함된 커서에 대한 레퍼런스를 반환할 수 있습니다. 커서에 저장된 데이터를 검사하는 방법을 알아보려면 커서 기본 사항 페이지를 참조하세요.
관련성 기준 정렬
이제 결과 세트가 원하는 결과를 반영하므로 쿼리 프로젝션에서 $meta 연산자를 사용하여 액세스하는 텍스트 검색 textScore
을 사용하여 결과를 관련성 순으로 정렬할 수 있습니다.
// Create a query that searches for the phrase "star trek" while omitting "into darkness"r const query = { $text: { $search: "\"star trek\" -\"into darkness\"" } }; // Sort returned documents by descending text relevance score const sort = { score: { $meta: "textScore" } }; // Include only the `title` and `score` fields in each returned document const projection = { _id: 0, title: 1, score: { $meta: "textScore" }, }; // Find documents based on the query, sort, and projection const cursor = movies .find(query) .sort(sort) .project(projection);
이 방법으로 쿼리하면 다음 문서가 다음 순서로 반환됩니다. 일반적으로 문자열이 더 많은 용어와 일치할수록 텍스트 관련성은 증가하고, 일치하지 않는 문자열의 부분이 길어질수록 관련성이 감소합니다.
{ title: 'Star Trek', score: 1.5 } { title: 'Star Trek: Generations', score: 1.3333333333333333 } { title: 'Star Trek: Insurrection', score: 1.3333333333333333 } { title: 'Star Trek: Nemesis', score: 1.3333333333333333 } { title: 'Star Trek: The Motion Picture', score: 1.25 } { title: 'Star Trek: First Contact', score: 1.25 } { title: 'Star Trek II: The Wrath of Khan', score: 1.2 } { title: 'Star Trek III: The Search for Spock', score: 1.2 } { title: 'Star Trek IV: The Voyage Home', score: 1.2 } { title: 'Star Trek V: The Final Frontier', score: 1.2 } { title: 'Star Trek VI: The Undiscovered Country', score: 1.2 }
$text 연산자 및 해당 옵션에 관한 자세한 내용은 매뉴얼 항목을 참조하세요.