Think back to our earlier example, where documents have a field named tags
. This is a multivalue field. A document may have one tag, many tags, or potentially no tags at all. If a field has no values, how is it stored in an inverted index?
tags
라 이름 붙여진 field를 가진 document가 있는, 초기 예제를 다시 생각해 보자. 이 field는 다중 값 field이다. document는 하나의 태그 또는 다수의 태그를 가질 수도 있고, 어쩌면 전혀 없을 수도 있다. 만약 field가 아무런 값도 가지지 않는다면, inverted index에는 어떻게 저장될까?
That’s a trick question, because the answer is: it isn’t stored at all. Let’s look at that inverted index from the previous section:
묘한 질문이다. 답은 전혀 저장하지 않는다 이다. 이전의 inverted index를 살펴보자.
Token | DocIDs |
|
|
|
|
How would you store a field that doesn’t exist in that data structure? You can’t! An inverted index is simply a list of tokens and the documents that contain them. If a field doesn’t exist, it doesn’t hold any tokens, which means it won’t be represented in an inverted index data structure.
해당 데이터 구조에 존재하지 않는 field를 어떻게 저장하겠는가? 할 수 없다. inverted index는 단순히 token과 token을 포함하고 있는 document의 목록이다. 만약 field가 존재하지 않는다면, 그것은 token을 가지고 있지 않다. 즉, inverted index 데이터 구조에서 그것을 표현할 수 없다는 의미이다.
Ultimately, this means that a null
, []
(an empty array), and [null]
are all equivalent. They simply don’t exist in the inverted index!
결국, 이것은 null
, []
(비어 있는 배열) 그리고 [null]
과 모두 동일하다는 것을 의미한다. 간단히 말해서, 그것들은 inverted index에 존재하지 않는다.
Obviously, the world is not simple, and data is often missing fields, or contains explicit nulls or empty arrays. To deal with these situations, Elasticsearch has a few tools to work with null or missing values.
알다시피, 이 세상은 간단하지 않다. 그리고, 데이터는 가끔 field를 누락하고, 명시적으로 null이나 비어있는 배열을 포함한다. 이런 상황에 대처하기 위해, Elasticsearch는 null이나 누락된 값을 다루기 위한, 몇 가지 도구를 가지고 있다.
exists Queryedit
The first tool in your arsenal is the exists
query. This query will return documents that have any value in the specified field. Let’s use the tagging example and index some example documents:
첫 번째 도구는 exists
query이다. 이 query는 지정한 field에 어떤 값을 가지는, document를 반환한다. 몇 개의 document를 색인하고, tagging 예제를 사용해 보자
POST /my_index/posts/_bulk { "index": { "_id": "1" }} { "tags" : ["search"] } { "index": { "_id": "2" }} { "tags" : ["search", "open_source"] } { "index": { "_id": "3" }} { "other_field" : "some data" } { "index": { "_id": "4" }} { "tags" : null } { "index": { "_id": "5" }} { "tags" : ["search", null] }
| |
| |
| |
| |
|
The resulting inverted index for our tags
field will look like this:
tags
field에 대한 inverted index의 결과는 아래와 같다.
Token | DocIDs |
|
|
|
|
Our objective is to find all documents where a tag is set. We don’t care what the tag is, so long as it exists within the document. In SQL parlance, we would use an IS NOT NULL
query:
tag가 설정된 모든 document를 찾는 것이 목적이다. document내에 태그가 존재하는 한, 태그가 무엇이든 관계없다. SQL에서는 IS NOT NULL
을 사용할 수 있다.
SELECT tags
FROM posts
WHERE tags IS NOT NULL
In Elasticsearch, we use the exists
query:
Elasticsearch에서는 exists
query를 사용한다.
GET /my_index/posts/_search { "query" : { "constant_score" : { "filter" : { "exists" : { "field" : "tags" } } } } }
Our query returns three documents:
query는 3개의 document를 반환한다.
"hits" : [ { "_id" : "1", "_score" : 1.0, "_source" : { "tags" : ["search"] } }, { "_id" : "5", "_score" : 1.0, "_source" : { "tags" : ["search", null] } }, { "_id" : "2", "_score" : 1.0, "_source" : { "tags" : ["search", "open source"] } } ]
document 5는 |
The results are easy to understand. Any document that has terms in the tags
field was returned as a hit. The only two documents that were excluded were documents 3 and 4.
결과는 이해하기 쉽다. tags
field에 단어를 가지고 있는 모든 document가 hit로 반환된다. 제외된 document는 3과 4뿐이다.
missing Queryedit
The missing
query is essentially the inverse of exists
: it returns documents where there is no value for a particular field, much like this SQL:
missing
query는 기본적으로 exists
의 반대이다. 특정 filed에 아무런 값이 없는 document가 반환된다. 아래 SQL과 매우 유사하다.
SELECT tags
FROM posts
WHERE tags IS NULL
Let’s swap the exists
query for a missing
query from our previous example:
위의 예제에서 exists
query를 missing
query로 바꾸어 보자.
GET /my_index/posts/_search { "query" : { "constant_score" : { "filter": { "missing" : { "field" : "tags" } } } } }
And, as you would expect, we get back the two docs that have no real values in the tags
field—documents 3 and 4:
기대했던 대로, tags
field에 실제로 어떤 값도 존재하지 않는, 2개(3과 4)의 document를 반환한다.
"hits" : [ { "_id" : "3", "_score" : 1.0, "_source" : { "other_field" : "some data" } }, { "_id" : "4", "_score" : 1.0, "_source" : { "tags" : null } } ]
exists/missing on Objectsedit
The exists
and missing
queries also work on inner objects, not just core types. With the following document
exists
와 missing
query는 기본(core) type이 아닌 inner 오브젝트에서도 동작한다. 아래 document를 보면,
{ "name" : { "first" : "John", "last" : "Smith" } }
you can check for the existence of name.first
and name.last
but also just name
. However, in Types and Mappings, we said that an object like the preceding one is flattened internally into a simple field-value structure, much like this:
name
뿐만 아니라 name.first
와 name.last
의 존재를 확인할 수 있다. 그러나, Types and Mappings에서, 위와 같은 오브젝트는, 아래처럼 단순한 field-value 구조로, 내부적으로 평면적이 된다고 이야기 했었다.
{ "name.first" : "John", "name.last" : "Smith" }
So how can we use an exists
or missing
query on the name
field, which doesn’t really exist in the inverted index?
그렇다면, 실제로 inverted index에 존재하지 않는 name
field에, exists
나 missing
query를 어떻게 사용할 수 있을까?
The reason that it works is that a filter like
그 이유는, 아래와 같은 filter는
{ "exists" : { "field" : "name" } }
is really executed as
실제로 아래와 같이 실행되기 때문이다.
{ "bool": { "should": [ { "exists": { "field": "name.first" }}, { "exists": { "field": "name.last" }} ] } }
That also means that if first
and last
were both empty, the name
namespace would not exist.
즉, first
와 last
가 모두 비어 있다면, name
namespace는 존재하지 않는 것이다.
'2.X > 2. Search in Depth' 카테고리의 다른 글
2-1-3. Finding Multiple Exact Values (0) | 2017.09.30 |
---|---|
2-1-4. Ranges (0) | 2017.09.30 |
2-1-6. All About Caching (0) | 2017.09.30 |
2-2. Full-Text Search (0) | 2017.09.30 |
2-2-1. Term-Based Versus Full-Text (0) | 2017.09.30 |