Post List

2015년 8월 8일 토요일

MongoDB Study #13 Index 실습 Part.3 Text Index

1. Text Index란 ?

Text Index는 Collection 내에 있는 String Content 에 대한 검색 기능을 제공해 줍니다.
특정 언어로 저장된 String 중 특정 단어를 찾아주는 것이 기본 검색 방법입니다.

2. 실습

2.1 선언

먼저 Index 선언 및 예제 Data들을 입력해 보겠습니다.

db.doc.createIndex( { txt: "text" } )
db.doc.insert( { txt: "Robots are superior to humans" } )
db.doc.insert( { txt: "Humans are weak" } )
db.doc.insert( { txt:"I, Robot - by Isaac Asimov"} ) 


db.doc.find()
{ "_id" : ObjectId("55c56a21d14bee62e1a96abe"), "txt" : "Robots are superior to humans"
{ "_id" : ObjectId("55c56a33d14bee62e1a96abf"), "txt" : "Humans are weak" }
{ "_id" : ObjectId("55c56a4cd14bee62e1a96ac0"), "txt" : "I, Robot - by Isaac Asimov" }

2.2 기본 검색

기본적인 검색을 몇가지 해보겠습니다.

db.doc.find( { $text : { $search : "robot" } } ) // 별도로 field 지정이 없는데도 text 로 index가 지정된 field 에서 검색
{ "_id" : ObjectId("55c56a21d14bee62e1a96abe"), "txt" : "Robots are superior to humans" }
{ "_id" : ObjectId("55c56a4cd14bee62e1a96ac0"), "txt" : "I, Robot - by Isaac Asimov" }

db.doc.find( { $text : { $search: "robot" } } ).length()
2

db.doc.find( { $text : { $search : "robot human" } } , { _id : 0 } ) // 여러 단어를 입력하면 OR 연산으로 처리 (순서, 대소문자는 상관없음)
{ "txt" : "Humans are weak" }
{ "txt" : "Robots are superior to humans" }
{ "txt" : "I, Robot - by Isaac Asimov" }


db.doc.find( { $text : { $search : "robot -human" } } ) // 부정(Negation) 연산을 하면 해당 단어를 제외
{ "_id" : ObjectId("55c56a4cd14bee62e1a96ac0"), "txt" : "I, Robot - by Isaac Asimov" }


db.doc.find( { $text : { $search : ' "robots are" ' } } ) // 큰 따옴표를 작은 따옴표로 감싸주면 AND 연산으로 처리
{ "_id" : ObjectId("55c56a21d14bee62e1a96abe"), "txt" : "Robots are superior to humans" }


db.doc.find( { $text : { $search : '"are robots"' } } ) // AND 연산은 바로 인접한 단어끼리 순서도 맞아야하고, 부분 단어는 처리가 안됨
db.doc.find( { $text : { $search : '"bots ar"' } } )
db.doc.find( { $text : { $search : '"robots are"' } } )

{ "_id" : ObjectId("55c56a21d14bee62e1a96abe"), "txt" : "Robots are superior to humans" }
db.doc.find( { $text : { $search : '"Robots to"' } } )

​2.3 언어 설정

먼저 독일어 로 설정한 Text에 대한 실습입니다.
Text 검색에는 배제되는 단어들이 있습니다. 영어의 a, the 라든지, 독일어의 ich, bin 이라든지...
그런 단어들은 검색이 되지 않습니다.

db.de.createIndex( { txt : "text" } , { default_language: "german" } )
db.de.insert( { txt: "Ich bin Dein Vater, Luke." } )


db.de.find( { $text : { $search : "Ich" } } )
db.de.find( { $text : { $search : "Luke" } } )

{ "_id" : ObjectId("55c57504d14bee62e1a96ac3"), "txt" : "Ich bin Dein Vater, Luke." }
db.de.find( { $text : { $search : "Vater" } } )
{ "_id" : ObjectId("55c57504d14bee62e1a96ac3"), "txt" : "Ich bin Dein Vater, Luke." }
db.de.find( { $text : { $search : "bin" } } )
db.de.find( { $text : { $search : "Dein" } } )
db.de.find( { $text : { $search : "dein" } } )
db.de.find( { $text : { $search : "vater" } } )

{ "_id" : ObjectId("55c57504d14bee62e1a96ac3"), "txt" : "Ich bin Dein Vater, Luke." }
db.de.find( { $text : { $search : "luke" } } )
{ "_id" : ObjectId("55c57504d14bee62e1a96ac3"), "txt" : "Ich bin Dein Vater, Luke." }

Luke 와 Vater에 대해서는 대소문자 구분없이 검색되지만, Ich, bin, Dein에 대해서는 정확히 Case 맞게 검색해도 결과가 안나옵니다.

그럼 여기에 똑같은 문장을 영어로 설정해서 입력해 보겠습니다.

db.de.insert( { txt: "Ich bin Dein Vater, Luke." , language : "english" } )

db.de.find( { $text : { $search : "Vater" } } )
{ "_id" : ObjectId("55c57504d14bee62e1a96ac3"), "txt" : "Ich bin Dein Vater, Luke." }
db.de.find( { $text : { $search : "Vater" , $language : "english" } } )
{ "_id" : ObjectId("55c57733d14bee62e1a96ac4"), "txt" : "Ich bin Dein Vater, Luke.", "language" : "english" }
db.de.find( { $text : { $search : "ich" , $language : "english" } } )
{ "_id" : ObjectId("55c57733d14bee62e1a96ac4"), "txt" : "Ich bin Dein Vater, Luke.", "language" : "english" }

collection의 기본 언어 설정이 독일어라서 검색시 언어 지정이 없으면 독일어 결과만을 보여줍니다.
영어에서는 Ich에 대해서도 대소문자 구분 없이 검색이 됩니다.

2.4 Multi-field Index

Text Index를 여러 Field에 대해서도 설정이 가능합니다.
이 경우 Field 마다 가중치(Weights)를 다르게 설정하여 Score 도 같이 검색 및 정렬(Sort)가 가능합니다.
Weights를 따로 설정하지 않으면 1로 처리됩니다.

db.mail.createIndex( { subject: "text" , body : "text" } , { weights : { subject : 10 } } )
db.mail.insert( { subject : "Robot leader to minions" , body : "Humans suck" , prio : 0 } )
db.mail.insert( { subject : "Human leader to minions" , body : "Robots suck" , prio : 1 } ) 

db.mail.find( {$text : { $search : "robot" } } )
{ "_id" : ObjectId("55c5793dd14bee62e1a96ac6"), "subject" : "Human leader to minions", "body" : "Robots suck", "prio" :1 }
{ "_id" : ObjectId("55c57930d14bee62e1a96ac5"), "subject" : "Robot leader to minions", "body" : "Humans suck", "prio" :0 }

db.mail.find( { $text : { $search : "robot" } } , { _id : 0 , score : { $meta : "textScore" } } )
{ "subject" : "Human leader to minions", "body" : "Robots suck", "prio" : 1, "score" : 0.75 }
{ "subject" : "Robot leader to minions", "body" : "Humans suck", "prio" : 0, "score" : 6.666666666666666 }

db.mail.find( { $text : { $search : "robot" } } , { _id : 0 , score : { $meta : "textScore" } } ).sort( { score : { $meta: "textScore" } } )
{ "subject" : "Robot leader to minions", "body" : "Humans suck", "prio" : 0, "score" : 6.666666666666666 }
{ "subject" : "Human leader to minions", "body" : "Robots suck", "prio" : 1, "score" : 0.75 }

db.mail.find( { $text : { $search : "robot"  } , prio : 0 } , { _id : 0 , score : { $meta : "textScore" } } )
{ "subject" : "Robot leader to minions", "body" : "Humans suck", "prio" : 0, "score" : 6.666666666666666 }

참조 Site

https://blog.codecentric.de/en/2013/01/mongodb-text-search-tutorial/

http://docs.mongodb.org/manual/reference/operator/query/text/

댓글 없음:

댓글 쓰기