Inverted Index - elastic search

김현우·2020년 9월 15일
0

Index

  1. index
  • key-value구조를 가지는 테이블
keyvalue
11번값
22번값
33번값
  1. forward index
  • Document가 Key에 해당하고 document에 존재하는 Word들이 Value에 해당
DocumentWords
doc1apple, bottle, toy
doc2grape, box
doc3snack, toy, box
  1. inverted index
  • Word가 Key가 되고, 그 Word가 존재하는 Document들이 Value가 된다
WordDocuments
appledoc1
boxdoc2, doc3
toydoc1, doc3

Standard Analyer

  1. 필드 타입이 text인 경우
text = 'The Fast white dog jumped over the lazy cat!'
tokenized_text = tokenizer(text)
  • 결과는 tokenized_text는 [fast, white, cat, jump, over, lazi, dog ]
  • the나 !와 같은 것들은 필터링하고 분리저장 (standard analyer O)
  1. 필드 타입이 keyword or number or date인 경우
  • keyword나 number, date와 같은 type의 field들은 그 값 자체로 찾기쉽도록 Inverted Index가 된다. (standard analyer X)

Elasticsearch

Open Source Project인 Apache Lucene을 기반으로 만들어진 빅데이터를 거의 실시간(NRT, Near Real Time)으로 저장, 검색 및 분석할 수 있는 오픈소스 검색 엔진

Import

import elasticsearch
from elasticsearch_dsl import Search, Q, Index

es = elasticsearch.Elasticsearch('localhost:9200')

Query

  1. match_all
s = Search(index='index_name', using=es)
s = s.query('match_all')
search_result = []
for hit in s.scan():
    search_result.append(hit)
  1. match
  • field가 text라면 유사한 값들을 반환
  • unique한 경우에는 하나만 찾아서 반환
s = Search(index='index_name', using=es)
s = s.query('match', pk=1)
res = s.execute()
res.to_dict()
  1. multi_match
  • 여러개의 field를 동시에 확인하는 방법
query_text = '브랜드명 상품명'
s = Search(index='item_storage', using=es)
s = s.query(
    'multi_match', 
    query=query_text, 
    fuzziness='auto', 
    fields=['item_name', 'brand_name']
)
  1. range
  • 범위 조건은 range를 이용
condition = {
    'gte': 10, 
    'lt': 20
}
s = Search(index='index_name', using=es)
s = s.filter('range', pk=condition)
res = s.execute()
res.to_dict()
  1. q를 사용하여 특정 값 filtering
s = Search(index='users').using(es)
must = [
  {'match': {'firstname.keyword': {'query': 'John'}}}
]
should = [
  {'match': {'lastname.keyword': 'Lennon'}},
  {'match': {'country': 'Korea'}}
]
s = s.query(Q('bool', must=must, should=should, minimum_should_match=1))
res = s.execute()

users index에서firstname이 John이면서 lastename이 Lennon이거나 country가 Korea인 유저를 찾아온다.

  1. terms
  • Inverted Index에서 정확히 일치하는 항목들을 반환

field data type

namedescription
textfull text를 의미. analyzer를 사용해서 inverted indexing(역색인)
keyword정확한 값들을 의미. 들어온 값 그대로 inverted indexing(역색인)

inverted Index type
| Field Name | Inverted Index |
|:----------|:----------:|
| full_text |[quick, foxes]|
| exact_value | [Quick Foxes!] |

  1. terms + sort
s = Search(index='index_name', using=es)
s = s.query('terms', pks=[0, 3, 5, 9]).sort('pk')

오름차순 pk, 내림차순 -pk

  1. source
  • 원하는 값들만 가져옴.
s = Search(index='users', using=es)
s = s.query('terms', pks=[0, 3, 5, 9]).sort('pk').source([
  'email',
  'profile_image'
])
profile
코딩을 잘하는 개발자가 되자!

0개의 댓글