<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jyo____c.log</title>
        <link>https://velog.io/</link>
        <description>뜨개질하는 개발자</description>
        <lastBuildDate>Thu, 04 Jul 2024 06:58:23 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jyo____c.log</title>
            <url>https://velog.velcdn.com/images/jyo____c/profile/e605b56b-b49c-4d6a-840d-d48ff217a1ac/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jyo____c.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jyo____c" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[elasticsearch watcher 신규 이벤트마다 webhook 발생]]></title>
            <link>https://velog.io/@jyo____c/elasticsearch-watcher-%EC%8B%A0%EA%B7%9C-%EC%9D%B4%EB%B2%A4%ED%8A%B8%EB%A7%88%EB%8B%A4-webhook-%EB%B0%9C%EC%83%9D</link>
            <guid>https://velog.io/@jyo____c/elasticsearch-watcher-%EC%8B%A0%EA%B7%9C-%EC%9D%B4%EB%B2%A4%ED%8A%B8%EB%A7%88%EB%8B%A4-webhook-%EB%B0%9C%EC%83%9D</guid>
            <pubDate>Thu, 04 Jul 2024 06:58:23 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-json">{
  &quot;trigger&quot;: {
    &quot;schedule&quot;: {
      &quot;interval&quot;: &quot;10s&quot;
    }
  },
  &quot;input&quot;: {
    &quot;search&quot;: {
      &quot;request&quot;: {
        &quot;indices&quot;: [&quot;your-index-name&quot;],
        &quot;body&quot;: {
          &quot;query&quot;: {
            &quot;bool&quot;: {
              &quot;must&quot;: [
                {
                  &quot;range&quot;: {
                    &quot;@timestamp&quot;: {
                      &quot;gte&quot;: &quot;now-10s&quot;
                    }
                  }
                },
                {
                  &quot;term&quot;: {
                    &quot;event_type&quot;: &quot;your_event_type&quot;
                  }
                }
              ]
            }
          },
          &quot;sort&quot;: [
            {
              &quot;@timestamp&quot;: {
                &quot;order&quot;: &quot;desc&quot;
              }
            }
          ]
        },
        &quot;size&quot;: 100
      }
    }
  },
  &quot;condition&quot;: {
    &quot;compare&quot;: {
      &quot;ctx.payload.hits.total&quot;: {
        &quot;gt&quot;: 0
      }
    }
  },
  &quot;actions&quot;: {
    &quot;send_webhook_foreach&quot;: {
      &quot;foreach&quot;: &quot;ctx.payload.hits.hits&quot;,
      &quot;max_iterations&quot;: 100,
      &quot;webhook&quot;: {
        &quot;method&quot;: &quot;POST&quot;,
        &quot;url&quot;: &quot;http://your-webhook-url&quot;,
        &quot;body&quot;: &quot;&quot;&quot;
        {
          &quot;event_id&quot;: &quot;{{ctx.payload._source.event_id}}&quot;,
          &quot;timestamp&quot;: &quot;{{ctx.payload._source.@timestamp}}&quot;,
          &quot;user&quot;: &quot;{{ctx.payload._source.user}}&quot;,
          &quot;action&quot;: &quot;{{ctx.payload._source.action}}&quot;,
          &quot;details&quot;: {{#toJson}}ctx.payload._source.details{{/toJson}}
        }
        &quot;&quot;&quot;,
        &quot;headers&quot;: {
          &quot;Content-Type&quot;: &quot;application/json&quot;
        }
      }
    }
  }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[elasticsearch watcher]]></title>
            <link>https://velog.io/@jyo____c/watcher</link>
            <guid>https://velog.io/@jyo____c/watcher</guid>
            <pubDate>Thu, 04 Jul 2024 06:57:04 GMT</pubDate>
            <description><![CDATA[<p>23일간 로그인하지 않은 사람에게 보내는 이메일 알림</p>
<pre><code class="language-json">#클로드 3.5 소네트
{
  &quot;trigger&quot;: {
    &quot;schedule&quot;: {
      &quot;cron&quot;: &quot;0 0 * * *&quot;  // 매일 자정에 실행
    }
  },
  &quot;input&quot;: {
    &quot;search&quot;: {
      &quot;request&quot;: {
        &quot;indices&quot;: [&quot;users-index&quot;],
        &quot;body&quot;: {
          &quot;query&quot;: {
            &quot;bool&quot;: {
              &quot;must_not&quot;: [
                {
                  &quot;range&quot;: {
                    &quot;last_login&quot;: {
                      &quot;gte&quot;: &quot;now-23d&quot;
                    }
                  }
                }
              ],
              &quot;must&quot;: [
                {
                  &quot;term&quot;: {
                    &quot;active&quot;: true
                  }
                }
              ]
            }
          }
        },
        &quot;size&quot;: 1000
      }
    }
  },
  &quot;condition&quot;: {
    &quot;compare&quot;: {
      &quot;ctx.payload.hits.total&quot;: {
        &quot;gt&quot;: 0
      }
    }
  },
  &quot;actions&quot;: {
    &quot;email_inactive_users&quot;: {
      &quot;foreach&quot;: &quot;ctx.payload.hits.hits&quot;,
      &quot;max_iterations&quot;: 1000,
      &quot;email&quot;: {
        &quot;to&quot;: &quot;{{_source.email}}&quot;,
        &quot;subject&quot;: &quot;Login Reminder&quot;,
        &quot;body&quot;: {
          &quot;html&quot;: &quot;&quot;&quot;
          &lt;p&gt;Dear {{_source.name}},&lt;/p&gt;
          &lt;p&gt;We noticed that you haven&#39;t logged in to our service for 23 days. 
          We miss you and hope to see you soon!&lt;/p&gt;
          &lt;p&gt;Best regards,&lt;br&gt;Your Service Team&lt;/p&gt;
          &quot;&quot;&quot;
        }
      }
    }
  }
}</code></pre>
<pre><code class="language-json">#챗gpt 3.5
PUT _watcher/watch/login_watch
{
  &quot;trigger&quot;: {
    &quot;schedule&quot;: {
      &quot;daily&quot;: { &quot;at&quot;: &quot;12:00&quot; }     // 매일 낮 12시에 실행
    }
  },
  &quot;input&quot;: {
    &quot;search&quot;: {
      &quot;request&quot;: {
        &quot;indices&quot;: [&quot;user-logs&quot;],    // 사용자 로그가 저장된 인덱스
        &quot;body&quot;: {
          &quot;query&quot;: {
            &quot;bool&quot;: {
              &quot;must_not&quot;: {
                &quot;range&quot;: {
                  &quot;last_login&quot;: {    // 마지막 로그인 시간 필드
                    &quot;gte&quot;: &quot;now-23d/d&quot;,
                    &quot;lte&quot;: &quot;now/d&quot;
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  &quot;condition&quot;: {
    &quot;compare&quot;: {
      &quot;ctx.payload.hits.total.value&quot;: {
        &quot;gt&quot;: 0     // 하나 이상의 사용자가 검색되면 실행
      }
    }
  },
  &quot;actions&quot;: {
    &quot;email_action&quot;: {
      &quot;email&quot;: {
        &quot;to&quot;: &quot;{{#ctx.payload.hits.hits}}{{_source.email}}{{/ctx.payload.hits.hits}}&quot;, // 사용자 이메일 주소
        &quot;subject&quot;: &quot;로그인 알림&quot;,
        &quot;body&quot;: &quot;귀하의 계정은 23일 동안 로그인하지 않았습니다.&quot;
      }
    }
  }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[쿠버네티스 환경에서 엘라스틱서치 클러스터링 (실패)]]></title>
            <link>https://velog.io/@jyo____c/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EC%97%98%EB%9D%BC%EC%8A%A4%ED%8B%B1%EC%84%9C%EC%B9%98-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0%EB%A7%81-%EC%8B%A4%ED%8C%A8</link>
            <guid>https://velog.io/@jyo____c/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EC%97%98%EB%9D%BC%EC%8A%A4%ED%8B%B1%EC%84%9C%EC%B9%98-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0%EB%A7%81-%EC%8B%A4%ED%8C%A8</guid>
            <pubDate>Fri, 03 May 2024 04:48:32 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch-node1
  namespace: branch
spec:
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      initContainers:
        - name: fix-permissions
          image: busybox
          command: [&#39;sh&#39;, &#39;-c&#39;, &#39;chown -R 1000:1000 /usr/share/elasticsearch/config&#39;, &#39;chown -R 1000:1000 /usr/share/elasticsearch/data&#39;]
          volumeMounts:
            - name: config-volume
              mountPath: /usr/share/elasticsearch/config
            - name: data-volume
              mountPath: /usr/share/elasticsearch/data
      containers:
        - name: elasticsearch
          image: docker.elastic.co/elasticsearch/elasticsearch:8.13.2
          securityContext:
            runAsUser: 1000
            runAsGroup: 1000
          env:
            - name: node.name
              value: &quot;node1&quot;
            - name: cluster.name
              value: &quot;elasticsearch-cluster&quot;
            - name: discovery.seed_hosts
              value: &quot;node1, node2, node3&quot;
            - name: cluster.initial_master_nodes
              value: &quot;node1, node2, node3&quot;
          volumeMounts:
            - name: config-volume
              mountPath: /usr/share/elasticsearch/config
            - name: data-volume
              mountPath: /usr/share/elasticsearch/data
      volumes:
        - name: config-volume
          hostPath:
            path: /data/containerd/elasticsearch/node1/config
            type: Directory
        - name: data-volume
          hostPath:
            path: /data/containerd/elasticsearch/node1/data
            type: Directory
      nodeSelector:
        name: node2</code></pre>
<pre><code class="language-yaml">apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-node
  namespace: branch
spec:
  clusterIP: None
  selector:
    app: elasticsearch
  ports:
    - port: 9201
      name: http
    - port: 9301
      name: transport</code></pre>
<pre><code class="language-yaml">apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-node1
  namespace: branch
spec:
  ports:
  - port: 9201
    name: rest
    targetPort: 31015
  - port: 9301
    name: transport
  clusterIP: None  # 이 설정이 서비스를 headless로 만듭니다.
  selector:
    app: elasticsearch
    node.name: &quot;node1&quot;  # 이 예시에서는 elasticsearch Pod의 라벨에 맞춰야 합니다.</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[쿠버네티스 환경에서 엘라스틱서치 싱글노드 띄우기]]></title>
            <link>https://velog.io/@jyo____c/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EC%97%98%EB%9D%BC%EC%8A%A4%ED%8B%B1%EC%84%9C%EC%B9%98-%EC%8B%B1%EA%B8%80%EB%85%B8%EB%93%9C-%EB%9D%84%EC%9A%B0%EA%B8%B0</link>
            <guid>https://velog.io/@jyo____c/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EC%97%98%EB%9D%BC%EC%8A%A4%ED%8B%B1%EC%84%9C%EC%B9%98-%EC%8B%B1%EA%B8%80%EB%85%B8%EB%93%9C-%EB%9D%84%EC%9A%B0%EA%B8%B0</guid>
            <pubDate>Fri, 03 May 2024 04:41:32 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch-node1 # 파드 이름
  namespace: branch # 어떤 네임스페이스에 띄울래?
spec:
  replicas: 1 # 띄울 파드 개수
  selector:
    matchLabels:
      app: elasticsearch # service랑 연결할 때 쓰는 selector 이름
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      initContainers: # container 보다 먼저 실행
      - name: fix-permissions
        image: busybox
        command: [&#39;sh&#39;, &#39;-c&#39;, &#39;chown -R 1000:1000 /usr/share/elasticsearch/config&#39;] # 권한 부여
        volumeMounts:
        - name: config-volume
          mountPath: /usr/share/elasticsearch/config
  containers:
    - name: elasticsearch
      image: docker.elastic.co/elasticsearch/elasticsearch:8.13.2
      securityContext: # 사용자와 사용자그룹 설정
        runAsUser: 1000
        runAsGroup: 1000
      env:
        - name: discovery.type
          value: single-node # 단일 노드로 설정
      volumeMounts:
        - name: config-volume
          mountPath: /usr/share/elasticsearch/config # config 폴더를 외부에서 가져옴

  volumes:
    - name: config-volume
      hostPath:
        path: /data/containerd/elasticsearch/node1 # 가져올 config 폴더 내용물 경로
        type: Directory
  nodeSelector: # 몇번 노드에 띄울지 지정
    name: node2</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[elasticsearch shard rebalancing]]></title>
            <link>https://velog.io/@jyo____c/elasticsearch-shard-rebalancing</link>
            <guid>https://velog.io/@jyo____c/elasticsearch-shard-rebalancing</guid>
            <pubDate>Mon, 26 Feb 2024 06:02:57 GMT</pubDate>
            <description><![CDATA[<h1 id="header">Header</h1>
<h3 id="해당-문서는-아래--공식-문서를-정리한-내용임">해당 문서는 아래  공식 문서를 정리한 내용임</h3>
<p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.16/modules-cluster.html">https://www.elastic.co/guide/en/elasticsearch/reference/7.16/modules-cluster.html</a></p>
<hr>
<h2 id="샤드-리밸런싱">샤드 리밸런싱</h2>
<p>클러스터의 어느 노드에도 샤드가 몰려있지 않고 같은 수준의 샤드 개수를 유지하고 있을 때 &#39;균형이 맞는다&#39;고 표현함.
엘라스틱 서치는 균형을 맞추기 위해서 노드 간에 샤드를 이동시키는 &#39;리밸런싱&#39;이라는 작업을 자동으로 실행함.
리밸런싱은 클러스터의 샤드 할당 규칙에 따르기 때문에 완벽할 수 없음.
이런 경우, 가장 완벽한 상태를 만드려고 시도함.
데이터 티어를 사용하는 경우에는 할당 규칙을 필터링하여 각 샤드를 적절한 티어에 배치함.</p>
<hr>
<h2 id="샤드-휴리스틱-리밸런싱">샤드 휴리스틱 리밸런싱</h2>
<p>리밸런싱은 각 노드의 무게를 계산한 후, 무거운 노드에서 가벼운 노드로 샤드를 이동시키며 발생함.
설정한 값 이하로 두 노드 간 차이를 좁힐 수 있는 이동이 더 이상 없을 때 균형을 잡았다고 함.</p>
<hr>
<h2 id="디스크-기반-샤드-할당">디스크 기반 샤드 할당</h2>
<p>디스크 기반 샤드 할당은 필요 이상의 샤드 이동을 막고, 모든 노드가 충분한 디스크 공간을 갖도록 함.
목표는 어떤 노드도 높은 워터마크를 갖지 않게 하는 것임.
리밸런싱 중 일시적으로 임계치를 넘어갈 수는 있으나 다른 노드로 다시 샤드를 리밸런싱하면서 해당 문제를 해결함.
일시적으로 높은 워터마크 이상의 디스크를 사용하는 것은 정상이라고 볼 수 있음.</p>
<blockquote>
<p>낮은 워터마크</p>
</blockquote>
<ul>
<li>샤드의 할당 작업 중단</li>
<li>기본 샤드는 새로 생성 가능</li>
</ul>
<blockquote>
<p>높은 워터마크</p>
</blockquote>
<ul>
<li>모든 샤드의 할당 작업 중단</li>
</ul>
<p>allocator는 낮은 워터마크를 초과한 노드에 더이상 샤드가 할당될 수 없도록 하여 높은 워터마크 초과를 방지함.
모든 노드가 높은 워터마크를 초과하면 샤드 할당이 불가능해지므로 일부 노드가 항상 낮은 워터마크보다 디스크를 적게 쓰는지 확인 작업이 필요함.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230515] ECE 기출 2회]]></title>
            <link>https://velog.io/@jyo____c/230515-TIL</link>
            <guid>https://velog.io/@jyo____c/230515-TIL</guid>
            <pubDate>Mon, 15 May 2023 08:47:50 GMT</pubDate>
            <description><![CDATA[<h1 id="task-1">task 1</h1>
<p>작성 후 날리는 쿼리문에서, index를 생성만 한다고 치면 <code>PUT</code>이 맞는데, 생성과 동시에 데이터를 인덱싱 하려면 <code>POST</code>가 맞지 않나 의문
또, 따로 타입을 지정하라는 요구사항이 없는데 mapping을 내가 작성해두는게 맞을지?</p>
<h1 id="task-2">task 2</h1>
<p>mapping은 source index 복사해오면 될 것 같고, 문제 조건을 잘 모르겠음
단순히 <code>title</code>필드를 <code>keyword</code> 타입으로 변경해서 검색이 안 되게 만들면 되는걸까?</p>
<h1 id="task-3">task 3</h1>
<p><code>coot_to</code>는 <code>_search</code> request를 날렸을 때 보이지 않음..
이거 말고 다른 옵션이 있는건가?
가이드 찾아봤는데 <code>mapping parameters</code>에서 내용 찾지 못했음
몰라서 안보이는건지도</p>
<h1 id="task-4">task 4</h1>
<p>기본 aggregation 작성 문제
작성은 했으나 확인은 해볼 수 없어서 아쉬움 (index 부재)</p>
<h1 id="task-5">task 5</h1>
<p>runtime field script를 작성하는 문제
마찬가지로 직접 확인해 볼 수 없어서 아쉬움</p>
<h1 id="task-6">task 6</h1>
<p>하위 aggregation이 있는 경우의 정렬 방법을 자꾸 잊어버림
그래도 가이드에서 서치 키워드를 인지했으니 괜찮을 듯!
실 index가 없어서 <code>web_traffic</code> 인덱스 활용하여 비슷한 조건으로 진행함</p>
<h1 id="task-7">task 7</h1>
<p><code>score는 검색 조건에 해당된 필드들의 수</code>라는 조건이 잘 이해되지 않는다..
그 외 두 가지 조건은 쿼리 작성 가능할 듯</p>
<h1 id="task-8">task 8</h1>
<p>일반적인 search 쿼리 작성 문제이나, 클러스터 두 개를 다 활용해야 함</p>
<h1 id="task-9">task 9</h1>
<p>repo와 snapshot 설정하는 문제
경로 문제로 고생했었는데, 키바나 사용하면 큰 문제 없었던 것으로 기억</p>
<h1 id="task-10">task 10</h1>
<p><code>search template</code> 작성하는 문제
크게 어려움 없음</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230510] Elastic Certificated Engineer Practice Exam 복습]]></title>
            <link>https://velog.io/@jyo____c/230510-TIL</link>
            <guid>https://velog.io/@jyo____c/230510-TIL</guid>
            <pubDate>Wed, 10 May 2023 05:04:53 GMT</pubDate>
            <description><![CDATA[<h1 id="task-1">task 1</h1>
<p>설정한 role과 user는 어떻게 테스트 할 수 있는지 질문할 것</p>
<p>user 생성 시, role을 여러 개 선택할 수 있는 것 같던데 선택한 role 사이에 권한이 충돌하면 어떻게 되는지?</p>
<ul>
<li>task1_role : 문제 조건에 맞는 role 설정
task1 이외의 모든 인덱스에 대해 read 권한만 가짐</li>
<li>test_role : 궁금해서 만들어본 role 설정
모든 인덱스에 대해 all 권한 부여</li>
</ul>
<p>하나의 유저에 <code>task1_role</code>과 <code>test_role</code> 모두 부여했는데 문제 없이 저장되었음</p>
<h1 id="task-2">task 2</h1>
<p>문제 없음! clear!</p>
<h1 id="task-3">task 3</h1>
<p>해설은 dynamic template 사용했는데, 결과만 맞으면 mapping을 하나하나 정의해도 시험에서 큰 문제 없는지?</p>
<h1 id="task-4">task 4</h1>
<p><code>ignore_missing</code>에 대한 이야기가 문제에 제시되지 않았는데, 해설에서는 해당 옵션을 <code>true</code>로 설정함
일반적으로 필수로 설정하는 옵션인가?</p>
<h1 id="task-5">task 5</h1>
<p>공식 문서에서 <code>nested field</code> 내용 확인</p>
<p>예시</p>
<pre><code>PUT my-index-000001/_doc/1
{
  &quot;group&quot; : &quot;fans&quot;,
  &quot;user&quot; : [
    {
      &quot;first&quot; : &quot;John&quot;,
      &quot;last&quot; :  &quot;Smith&quot;
    },
    {
      &quot;first&quot; : &quot;Alice&quot;,
      &quot;last&quot; :  &quot;White&quot;
    }
  ]
}</code></pre><ul>
<li><p><code>user</code>가 <code>nested field</code>가 아닌 경우</p>
<pre><code>GET my-index-000001/_search
{
&quot;query&quot;: {
  &quot;bool&quot;: {
    &quot;must&quot;: [
        {&quot;match&quot;: {&quot;user.first&quot;: &quot;John&quot;}},
      {&quot;match&quot;: {&quot;user.last&quot;: &quot;White&quot;}}
    ]
  }
}
}</code></pre><p>위와 같은 요청을 전송하면 <code>hit</code>이 1개가 도출됨
<code>user</code>필드 내부의 요소 두 개를 하나의 단위로 보지 않고, 전체를 하나의 document로 취급하기 때문</p>
</li>
<li><p><code>user</code>가 <code>nested field</code>인 경우</p>
<pre><code>GET my-index-000001/_search
{
 &quot;query&quot;: {
  &quot;nested&quot;: {
    &quot;path&quot;: &quot;authors&quot;,
    &quot;query&quot;: {
      &quot;bool&quot;: {
        &quot;must&quot;: [
          {&quot;match&quot;: {&quot;user.first_name&quot;: &quot;John&quot;}},
          {&quot;match&quot;: {&quot;user.last_name&quot;: &quot;White&quot;}}
        ]
      }
    }
  }
}</code></pre><p>먼저의 예시와 유사한 검색이지만, 이 요청의 응답은 <code>hit</code>이 0개.
<code>user</code>가 <code>nested field</code>이므로 그 내의 객체 하나하나를 하나의 작은 단위로 보기 때문
필드 하나하나를 보지 않고 객체를 검색한다고 이해하면 맞을 듯</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230509] practice exam 1]]></title>
            <link>https://velog.io/@jyo____c/230509-TIL</link>
            <guid>https://velog.io/@jyo____c/230509-TIL</guid>
            <pubDate>Tue, 09 May 2023 07:45:55 GMT</pubDate>
            <description><![CDATA[<h1 id="task-1">task 1</h1>
<p>조건에 맞추어 User와 Role 설정하는 문제
lab에서 실습하지 않은 내용이지만, 키바나 잘 확인하면 무리 없이 작성 가능</p>
<h1 id="task-2">task 2</h1>
<p>query를 사용해 범위를 좁히고, 중첩 구조의 aggregation을 진행하는 문제
lab에서 진행하던 것과 상황 설정만 다를 뿐, 거의 같음</p>
<h1 id="task-3">task 3</h1>
<p><code>dynamic templates</code> 사용하는 것 이외에는 lab 실습과 크게 다를 것 없는 문제
<code>dynamic</code> 개념을 완전 뒤로하고 있었는데 개념 상기도 되고 실습을 처음 진행해보기도 했음
실제 시험 중에는 답안을 확인할 수 없으니, 메뉴얼의 드롭다운을 모두 확인해보면서 어떤 개념이 있는지 미리 살펴보고, 시험 중에라도 막히는 경우 메뉴얼 싹 훑어보는 것이 좋을 듯</p>
<h1 id="task-4">task 4</h1>
<p>특정 필드에 대해 따로 타입 설정 해주지 않는 것 확인함..
코드도 에러로 동작하지 않음 ㅠㅠ
-&gt; 하나하나 비교해가면서 다시 뜯어볼 예정
=&gt; <code>ingest pipeline</code> 작성할 때에 오타가 있었던 것으로 확인!
문제지의 <code>answer</code>보다 더 정답에 가깝다고 생각함
문제에서는 <code>runtime_ms</code>, <code>bytes_sent</code>, <code>@timestamp</code> 이외는 모두 <code>keyword</code> 타입으로 지정하라고 되어있는데 답안에는 <code>response</code>에 대한 타입 지정이 누락되었음</p>
<h1 id="task-5">task 5</h1>
<p><code>nested</code>라는 새로운 type과 aggregation.
가이드 활용하면 크게 어렵지는 않았음</p>
<h1 id="task-6">task 6</h1>
<p>lab에서 실습한 내용과 거의 똑같은 문제라 금방 해결</p>
<h1 id="task-7">task 7</h1>
<p><code>remote cluster</code> 등록에 문제가 있어 진행할 수 없었음</p>
<h1 id="task-8">task 8</h1>
<p>키바나로 조건에 맞추어 <code>liftcycle policy</code>를 만드는 자체는 금방 진행
<code>matrics-mapping</code> component template을 사용하라는 조건이 있는데, 이 매핑 템플릿을 작성하는 것에 대한 내용은 존재하지 않음
실습때도 어려워했고, 현재도 잘 못 따라가는 파트라 반복 필요</p>
<h1 id="task-9">task 9</h1>
<p>스냅샷을 restore해서 검색을 진행하는 문제
실습해 본 적은 없지만, 가이드 보고 따라할 수 있을 것 같음
실제 스냅샷이 서버에 존재하지는 않아 눈으로 보고 이해</p>
<h1 id="task-10">task 10</h1>
<p>검색할 때 사용할 수 있는 다양한 옵션들 종합 선물 세트 문제
다 문제 없이 잘 진행했고, 잘 안 써봐서 옵션이 헷갈렸던 <code>highlight</code>도 가이드 참고하여 진행하였음
다만, pagenation할 때, from을 <code>시작 document 순서</code>가 아니라 <code>페이지 그 자체</code>로 오해한 바람에 잘못된 숫자를 지정함
실전 때 이런 디테일에 신경쓸 것</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230508] module 5~8 복습]]></title>
            <link>https://velog.io/@jyo____c/230508-TIL</link>
            <guid>https://velog.io/@jyo____c/230508-TIL</guid>
            <pubDate>Mon, 08 May 2023 09:00:34 GMT</pubDate>
            <description><![CDATA[<p>5.2장 solution 5번</p>
<pre><code>#request
GET web_traffic/_search
{
  &quot;size&quot;: 0,
  &quot;aggs&quot;: {
    &quot;status_code_buckets&quot;: {
      &quot;terms&quot;: {
        &quot;field&quot;: &quot;http.response.status_code&quot;,
        &quot;order&quot;: {
          &quot;runtime.50&quot;: &quot;asc&quot;
        }
      },
      &quot;aggs&quot;: {
        &quot;runtime&quot;: {
          &quot;percentiles&quot;: {
            &quot;field&quot;: &quot;runtime_ms&quot;,
            &quot;percents&quot;: [
              50
            ]
          }
        }
      }
    }
  }
}

#response
...
...
  &quot;aggregations&quot; : {
    &quot;status_code_buckets&quot; : {
      &quot;doc_count_error_upper_bound&quot; : 0,
      &quot;sum_other_doc_count&quot; : 230,
      &quot;buckets&quot; : [
        {
          &quot;key&quot; : &quot;503&quot;,
          &quot;doc_count&quot; : 1821,
          &quot;runtime&quot; : {
            &quot;values&quot; : {
              &quot;50.0&quot; : 158.0
            }
          }
        },
        ...
        ...</code></pre><p><code>runtime</code>이라고 이름을 붙인 aggregation의 결과를 보면, <code>runtime</code> 내에 <code>values</code>가 있고, 또 이 내부에 <code>50.0</code>과 그 결과가 있는 구조임
이 결과를 활용해서 정렬을 진행하는 것이 문제의 핵심인데, request를 보면 <code>runtime.50</code>으로 활용하고 있는 것을 확인할 수 있음</p>
<p>내가 생각하기에는 활용하는 값은 <code>runtime.values.50</code>이 되어야 맞는 것 같았는데.
<code>runtime.10</code>으로 변경해도 잘 작동하는 것을 확인함
<code>percentiles</code> aggregation은 데이터를 다 계산한 결과를 가지고 있고, 내가 그 중에서 어떤 데이터만 출력할지를 지정해주는 방식인 듯</p>
<hr>
<p><code>GET _cat/indices?v</code>에서 결과로 나오는 <code>docs.deleted</code>가 실제로 지금까지 해당 인덱스에서 지워진 document 개수인지 궁금해짐</p>
<p>5개의 document를 가진 인덱스를 임의 생성하고 <code>GET _cat/indices?v</code> 해보면 <code>docs.count</code>가 5개인 것을 확인 가능함
이후 하나의 document를 삭제한 후, 해당 인덱스에 <code>match_all</code> request를 날려 document 수가 4개인 것을 확인함
이후 다시 <code>GET _cat/indices?v</code> 해봤는데, 여전히 <code>docs.count</code>가 5개로 확인됨
실시간으로 인덱스들의 정보를 가져오는 것이 아니라 일정 시간마다 업데이트 하는 방식인 듯</p>
<p>어느 정도 지난 후 다시 <code>GET _cat/indices?v</code> 확인해보니, <code>docs.count</code>가 4개로 줄어들었음
그런데 의문인 점은, <code>docs.deleted</code>가 2개로 보인다는 것</p>
<hr>
<p>위 내용 작성하다가 다시 궁금해진 내용</p>
<p>인덱스 별로 <code>지금까지 삭제한 document 수</code>를 저장하고 있는 것인지,
아니면 <code>isDeleted</code> 같은 안 보이는 필드가 있고, 삭제 처리된 document에 대해 그 필드 값이 <code>true</code>로 변경되는 방식으로, <code>docs.deleted</code>의 값은 이 필드가 <code>true</code>인 document들을 세는 것일지?
만약에 후자라면 삭제한 document의 복구도 비교적 쉽게 이루어질 수 있을 듯</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230504] module 1~4 복습]]></title>
            <link>https://velog.io/@jyo____c/230504TIL</link>
            <guid>https://velog.io/@jyo____c/230504TIL</guid>
            <pubDate>Thu, 04 May 2023 08:53:27 GMT</pubDate>
            <description><![CDATA[<p><code>highlight</code>내에서 <code>pre_tags</code>, <code>post_tags</code>로 사용할 태그를 지정할 수 있음</p>
<pre><code>  ...
  &quot;highlight&quot;: {
    &quot;pre_tags&quot;: [&quot;&lt;strong&gt;&quot;],
    &quot;post_tags&quot;: [&quot;&lt;/strong&gt;&quot;]
  }
  ...</code></pre><p><code>[]</code>로 감싸져 있어서 여러 개의 태그를 담을 수 있을 것이라고 생각했고, 아래처럼 작성해봄</p>
<pre><code>  ...
  &quot;highlight&quot;: {
    &quot;pre_tags&quot;: [&quot;&lt;strong&gt;&quot;, &quot;&lt;b&gt;&quot;],
    &quot;post_tags&quot;: [&quot;&lt;/strong&gt;&quot;, &quot;&lt;/b&gt;&quot;]
  }
  ...</code></pre><p>그런데 여전히 결과는 <code>&lt;strong&gt;</code>, <code>&lt;/strong&gt;</code> 태그로만 감싸져 나오고 <code>&lt;b&gt;</code>, <code>&lt;/b&gt;</code> 태그는 보이지 않음</p>
<hr>
<p><code>Painless</code> 스크립트를 활용했을 때, 반환값을 볼 수 있는 방법은 없을까?</p>
<hr>
<p>4.3장 solution 2에서는 값을 꺼낼 때, <code>doc[&#39;url&#39;].value</code>로 꺼냈음
solution 3에서는 <code>doc[&#39;authors.last_name&#39;]</code>을 변수 <code>authors</code>에 저장해 둠
그리고 사용할 때, <code>authors.get(숫자).startsWidh()</code> 으로 사용함
구조를 잘 모르겠다.</p>
<p>내가 생각하기에는 3에서
-&gt; 꺼낼 때 <code>doc[&#39;authors.last_name&#39;].value</code>
-&gt; 혹은 사용할 때 <code>authors.get(숫자).value.startsWidh()</code>
위 두 경우 중 하나에 해당해야 맞는 것 같은데.</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230503] module 5~8 복습]]></title>
            <link>https://velog.io/@jyo____c/230503-TIL</link>
            <guid>https://velog.io/@jyo____c/230503-TIL</guid>
            <pubDate>Wed, 03 May 2023 08:49:18 GMT</pubDate>
            <description><![CDATA[<p><code>constant keyword</code> 필드를 <code>data stream</code> 인덱스에 설정해두면 <code>rollover</code> 될 때마다 가장 처음 들어오는 document에 의해 그 값이 결정됨
default로 <code>rollover</code> 되어도 같은 값을 유지하게 할 수 있음
-&gt; 모든 인덱스가 같은 값을 가진다면, 무슨 의미가 있는지?
어떤 상황에 주로 사용하는지?
예시가 잘 상상이 안 됨. 질문할 것</p>
<hr>
<p>7.4장 sanpshot repository 만드는 데에서 자꾸 실패
실습 불가능</p>
<hr>
<p>CCR 실습 결국 못해봄...
설정 관련된 내용을 공식 문서랑 자료에서 못 찾았다ㅠ
앞 부분 복습 후 리뷰타임 때에 yml 파일 관련 설정 질문 예정
CCR 하나에 매달리기보다 전체 복습 1번을 더 하자고 판단</p>
<hr>
<p><code>profiler</code>에서 <code>self time</code>이랑 <code>total time</code>의 차이점?</p>
<hr>
<p><code>boosting</code>의 두 가지 방법</p>
<ul>
<li><code>best_fields</code> : default. 여러 필드들의 점수를 내고 그 필드들 중 가장 높은 점수를 가지고 있는 하나의 필드를 선택해 그 점수가 document의 <code>score</code>가 됨</li>
<li><code>most_field</code> : 여러 필드들의 점수를 내고, 그 점수들의 합계가 해당 document의 <code>score</code>가 됨</li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230502] module 1~4 복습]]></title>
            <link>https://velog.io/@jyo____c/230502-TIL</link>
            <guid>https://velog.io/@jyo____c/230502-TIL</guid>
            <pubDate>Tue, 02 May 2023 08:57:12 GMT</pubDate>
            <description><![CDATA[<p>1.2장 solution2번</p>
<p>답안에는 PUT으로 되어있는데, POST로 작성해도 문제 없이 돌아가긴 함
<img src="https://velog.velcdn.com/images/jyo____c/post/7abc5ecc-1efd-4694-8102-8e22e4c7a04f/image.png" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/jyo____c/post/1491cd55-730e-403a-8f7f-88cf9d007914/image.png" alt="">
<code>t2_my_index</code>에서 자료를 보면 하나밖에 안 들어있는데, <code>Index Management</code> 메뉴에서 보면 document가 2개로 뜸
<img src="https://velog.velcdn.com/images/jyo____c/post/9477092b-baab-4646-af62-989173ad8dc2/image.png" alt="">
하나는 뭘까?</p>
<hr>
<p><img src="https://velog.velcdn.com/images/jyo____c/post/43281f1d-0b0c-4d02-8840-beb0ecbe6a42/image.png" alt="">
<code>blogs</code> 인덱스도 자료 개수가 4719개로 뜨는데, <code>Index Management</code>에서 보면 두 배로 나옴
혹시 replica에 저장된 document 개수까지 해서 이렇게 나오는건가?</p>
<hr>
<pre><code>GET t2_blogs_fixed2/_search
{
  &quot;size&quot;: 5, 
  &quot;query&quot;: {
    &quot;match_phrase&quot;: {
      &quot;content&quot;: &quot;open source&quot;
    }
  },
  &quot;sort&quot;: [
    {
      &quot;publish_date&quot;: {
        &quot;order&quot;: &quot;desc&quot;
      }
    }
  ],
  &quot;_source&quot;: [&quot;title&quot;, &quot;publish_date&quot;]
}

GET t2_blogs_fixed2/_search
{
  &quot;size&quot;: 5, 
  &quot;query&quot;: {
    &quot;match_phrase&quot;: {
      &quot;content&quot;: &quot;open source&quot;
    }
  },
  &quot;_source&quot;: [&quot;title&quot;, &quot;publish_date&quot;]
}</code></pre><p>위 아래는 <code>sort</code>가 있는지 없는지만 다름
<code>sort</code>가 있을 때에는 <code>score</code>가 <code>null</code>인 것을 확인함
<code>sort</code>를 빼면 각 document에 맞는 <code>score</code>가 계산됨
정렬 방식을 내가 지정하면 <code>score</code> 계산을 따로 진행하지 않는 듯</p>
<hr>
<pre><code>GET t2_blogs_fixed2/_search
{
  &quot;query&quot;: {
    &quot;bool&quot;: {
      &quot;must&quot;: [
        {
          &quot;multi_match&quot;: {
            &quot;query&quot;: &quot;meetups&quot;,
            &quot;fields&quot;: [&quot;title&quot;, &quot;content&quot;]
          }
        }
      ],
      &quot;filter&quot;: [
        {
          &quot;range&quot;: {
            &quot;publish_date&quot;: {
              &quot;gte&quot;: &quot;now-3y&quot;
            }
          }
        }
      ]
    }
  }
}

GET t2_blogs_fixed2/_search
{
  &quot;query&quot;: {
    &quot;bool&quot;: {
      &quot;must&quot;: [
        {
          &quot;multi_match&quot;: {
            &quot;query&quot;: &quot;meetups&quot;,
            &quot;fields&quot;: [&quot;title&quot;, &quot;content&quot;]
          }
        }
      ],
      &quot;filter&quot;: [
        {
          &quot;range&quot;: {
            &quot;publish_date&quot;: {
              &quot;gte&quot;: &quot;now/d-3y&quot;
            }
          }
        }
      ]
    }
  }
}</code></pre><p>위쪽 코드가 내가 작성한 방식, 아래쪽 코드가 solution 답안
검색할 자료의 기간을 설정할 때, <code>now-3y</code>인지 <code>now/d-3y</code>인지 표현 방식만 다름
결과는 동일한데, <code>now/d</code>의 정확한 의미가 궁금</p>
<hr>
<p><code>match</code>와 <code>term</code>의 차이가 뭘까?
같은 기능인데 단순히 <code>must</code>는 <code>match</code>, <code>filter</code>는 <code>term</code>을 쓰는건가?
기능이 같다면 두 가지 함수가 있는 이유는 <code>score</code> 계산의 유무 차이인가?
<code>score</code> 계산을 할지 말지는 <code>match</code>, <code>filter</code>를 선언하는 순간 정해질텐데...
비슷한 고민을 했던 것 같은데 명확히 해결되지 않은 모양
질문 후 따로 정리할 것</p>
<hr>
<p>pipeline 만들고 적용하고 하는 부분은 아직도 어색..
4장 여러번 돌려야 할 듯</p>
<hr>
<p>이름 겹치면 안 돌아갈 줄 알았는데 <code>runtime_mappings</code>를 통해서 이미 있던 필드 위에 타입을 일시적으로 덧씌울 수도 있음</p>
<hr>
<p><code>significant_terms</code>가 <code>terms</code>보다 상세한 정보가 나오는 것은 확인
그런데 <code>bg_count</code>는 뭘까?</p>
<pre><code>  &quot;aggregations&quot; : {
    &quot;top_OS&quot; : {
      &quot;doc_count_error_upper_bound&quot; : 11,
      &quot;sum_other_doc_count&quot; : 38389,
      &quot;buckets&quot; : [
        {
          &quot;key&quot; : &quot;Windows&quot;,
          &quot;doc_count&quot; : 517774,
          &quot;top_urls&quot; : {
            &quot;doc_count&quot; : 517774,
            &quot;bg_count&quot; : 1462658,
            &quot;buckets&quot; : [
              {
                &quot;key&quot; : &quot;/blog/welcome-insight-io-to-the-elastic-team&quot;,
                &quot;doc_count&quot; : 38455,
                &quot;score&quot; : 0.058338717766485755,
                &quot;bg_count&quot; : 60841
              },
              {
                &quot;key&quot; : &quot;/blog/configuring-ssl-tls-and-https-to-secure-elasticsearch-kibana-beats-and-logstash&quot;,
                &quot;doc_count&quot; : 7369,
                ...
                ...</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[230428] module 7,8 실습 기록]]></title>
            <link>https://velog.io/@jyo____c/230428-TIL</link>
            <guid>https://velog.io/@jyo____c/230428-TIL</guid>
            <pubDate>Fri, 28 Apr 2023 06:25:00 GMT</pubDate>
            <description><![CDATA[<p>aliases 실습 과정 중에서 궁금한 점이 생겼다.</p>
<pre><code>POST t2-my-metrics/_rollover
{
  &quot;conditions&quot;: {
    &quot;max_age&quot;: &quot;2s&quot;
  }
}

GET t2-my-metrics</code></pre><p>위 코드를 순서대로 실행하면, 현재 write 설정된 인덱스는 2초간만 유효하기 때문에 바로 다음 넘버링 인덱스가 생성된다.
그런데 이 설정이 계속 유지되는 건 아닌지 다음 넘버링이 나는 2초마다 생길 줄 알았는데, 한 번 생기고 그 다음 넘버링 인덱스가 생성되지 않는 것을 확인했다.
자동으로 매 시간마다 넘겨주거나 매 document의 수마다 넘겨주는 설정이 분명 있을텐데.</p>
<hr>
<p>7.1장에서 aliases 실습으로 만든 인덱스들은 index management 화면에서 보였는데,
7.2장에서 data stream 실습으로 만든 인덱스들은 찾아볼 수가 없다... 왜?</p>
<hr>
<pre><code>PUT _cluster/settings
{
  &quot;persistent&quot;: {
    &quot;indices.lifecycle.poll_interval&quot;: &quot;30s&quot;
  }
}</code></pre><p>poll interval이 정확히 어떤 것에 대한 간격인지 잘 모르겠음
일반적으로는 10분으로 설정한다는데, lifecycle에 대한 확인 시간인가?</p>
<hr>
<p>7.3장 lifecycle 설정하는 부분
=&gt; 약간의 오차는 있지만 이건 서버적인 부분에서 발생할 수 있는 틱 차이라고 생각되는 짧은 시간이고, 새 인덱스가 잘 생성되고 이전 인덱스는 warm 단계로 잘 내려옴
그런데 warm 단계에서 cold 단계로 내려오는 과정이 전혀 관찰되지 않음
설정이 뭔가 잘못된건지 리뷰 시간에 확인이 필요</p>
<pre><code>PUT _cluster/settings
{
  &quot;persistent&quot;: {
    &quot;indices.lifecycle.poll_interval&quot;: &quot;30s&quot;
  }
}

DELETE _data_stream/t2-my_metrics-service.status-dev

POST t2-my_metrics-service.status-dev/_doc
{
  &quot;@timestamp&quot;: &quot;2021-07-04&quot;,
  &quot;status&quot;: &quot;UP&quot;,
  &quot;message&quot;: &quot;Service is running.&quot;
}

GET t2-my_metrics-service.status-dev/_settings

GET t2-my_metrics-service.status-dev/_ilm/explain</code></pre><p>빠른 테스트 위한 코드 모음</p>
<hr>
<p><code>cluster2</code>의 <code>t1_blogs</code> 상태
<img src="https://velog.velcdn.com/images/jyo____c/post/68a5b4e2-2931-494b-be43-a526b4e0431d/image.png" alt=""></p>
<p><code>cluster1</code>의 <code>replicated_blogs</code> 상태
<img src="https://velog.velcdn.com/images/jyo____c/post/4457ecad-4ad3-47ef-b1d3-7e68eac66ca1/image.png" alt=""></p>
<p><code>CCR</code> 정의
<img src="https://velog.velcdn.com/images/jyo____c/post/51b9b519-bb1f-444c-bedb-994983a4d5b8/image.png" alt=""></p>
<p>follower 인덱스도 primary, replica 각 1개씩인데 왜 health 상태도 안 뜨고 복제도 안 될까...ㅠ</p>
<hr>
<p>8.3장의 6번 솔루션이 이해가 잘 되지 않음
should는 점수 계산에 영향을 미치지만 검색되는 자료의 수에는 영향을 미치지 않음
match 역시 점수 계산에 영향을 미치는 것은 같지만 결과에까지도 영향을 주는데...
뭘 어떻게 바꾸라는건지 잘 모르겠음
=&gt; should 내에서 match_phrase나 match나 결과는 크게 변하지 않지만 match_phrase가 상대적으로 연산 속도가 훨씬 느리기 때문에, 사용할 일이 있을 경우 match가 효율적</p>
<p>3단어 문장을 검색했을 때</p>
<ul>
<li>match_phrase : 1.3ms</li>
<li>match : 각 단어에 0.1ms</li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230426] module 5~6 실습 기록]]></title>
            <link>https://velog.io/@jyo____c/230426-TIL</link>
            <guid>https://velog.io/@jyo____c/230426-TIL</guid>
            <pubDate>Wed, 26 Apr 2023 09:00:33 GMT</pubDate>
            <description><![CDATA[<p>5.3의 5번 solution</p>
<pre><code>GET web_traffic/_search
{
  &quot;size&quot;: 0,
  &quot;aggs&quot;: {
    &quot;logs_by_week&quot;: {
      &quot;date_histogram&quot;: {
        &quot;field&quot;: &quot;@timestamp&quot;,
        &quot;calendar_interval&quot;: &quot;hour&quot;
      },
      &quot;aggs&quot;: {
        &quot;sum_bytes&quot;: {
          &quot;sum&quot;: {
            &quot;field&quot;: &quot;bytes_sent&quot;
          }
        },
        &quot;the_movfn&quot;: {
          &quot;moving_fn&quot;: {
            &quot;buckets_path&quot;: &quot;sum_bytes&quot;,
            &quot;window&quot;: 5,
            &quot;script&quot;: &quot;MovingFunctions.unweightedAvg(values)&quot;
          }
        }
      }
    }
  }
}
</code></pre><p><code>moving_fn</code>이 어떤 역할을 하는지 잘 모르겠음</p>
<hr>
<p>6.1의 7번 solution
=&gt; node 3번이 보이지 않음
primary 1, 2번이 각각 node1, node2에 배치된것은 확인했는데,
replicas는 왜 모두 unassigned인지 의문</p>
<hr>
<p><code>_cat/shard?v&amp;s=,,,&amp;h=,,,</code>에서 <code>s</code>,<code>h</code>가 각각 무슨 의미일까
=&gt; 하나씩 실행해보니, h는 어떤 항목을 표시할지 결정하는 부분
s는 sort. 어떤 기준으로 정렬할지 앞쪽부터 우선순위</p>
<hr>
<p><code>GET _tasks?actions=*reindex&amp;detailed</code>
runtime error 발생했을 때, 아직 해당 쿼리가 백그라운드에서 돌아가고 있을 수 있음
그 때에 돌아가고 있을 작업을 확인하는 것</p>
<p>아마 뒤에 <code>reindex</code>를 명시해서 <code>_reindex</code> 작업에 대한 디테일만 나오는 것 같은데, 다양한 옵션이 있을 것으로 예상
=&gt; 공부해볼 내용</p>
<hr>
<p>document를 저장할 때, 어떤 샤드에 저장하는가는 랜덤? 아니면 규칙이 있나?
=&gt; 질문할 것
==&gt; 기본적으로는 특정 알고리즘 (아마 라운드로빈)을 따름
내가 직접 어떤 샤드에 저장할 지 선택할 수도 있음</p>
<hr>
<p>오늘 실습 전반적으로 이해 잘 되었으나 <code>replica</code> 샤드들이 전혀 배치되지 않는 것을 확인했음
내가 무언가 설정을 잘못한건지 뭔지...
<code>primary</code>는 문제 없이 할당되는데 왜 모든 <code>replica</code>들이 unasigned로 표기될까</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230425] module 3~4 실습 기록]]></title>
            <link>https://velog.io/@jyo____c/230425-TIL</link>
            <guid>https://velog.io/@jyo____c/230425-TIL</guid>
            <pubDate>Tue, 25 Apr 2023 08:25:31 GMT</pubDate>
            <description><![CDATA[<p><code>_source</code>는 따로 설정해주지 않으면 default로 원본 자료의 모든 필드가 이 안에 담겨서 출력
<code>&quot;_source&quot;: [&quot;필드명&quot;, ...]</code>으로 어떤 필드만 담을지 선택할 수도 있음
<code>&quot;_source&quot;: false</code>로 설정하면 해당하는 document의 인덱스 명과 id만 출력</p>
<p>특정 필드만 필요한 경우에는 <code>fields</code>가 더 효율적</p>
<hr>
<pre><code>GET t2_blogs_fixed2/_search
{
  &quot;query&quot;: {
    &quot;match&quot;: {
      &quot;content&quot;: {
        &quot;query&quot;: &quot;open source&quot;,
        &quot;operator&quot;: &quot;and&quot;
      }
    }
  }
}</code></pre><p><code>match</code>는 기본적으로 <code>or</code>연산 수행
<code>and</code>연산을 위해서는 <code>match</code>내에 query를 한 번 더 작성해서 <code>&quot;operator&quot;: &quot;and&quot;</code>로 연산자를 설정해야 함</p>
<hr>
<p>구분자로 구분된 문자열 각각이 아니라 전체 문자열을 검색어로 사용하고 싶을 때에는 <code>match</code> 대신 <code>match_phrase</code> 사용</p>
<hr>
<pre><code>GET t2_blogs_fixed2/_search
{
  &quot;query&quot;: {
    &quot;multi_match&quot;: {
      &quot;query&quot;: &quot;meetups&quot;,
      &quot;fields&quot;: [&quot;title&quot;, &quot;content&quot;]
    }
  }
}

GET t2_blogs_fixed2/_search
{
  &quot;query&quot;: {
    &quot;range&quot;: {
      &quot;publish_date&quot;: {
        &quot;gte&quot;: &quot;now-3y&quot;
      }
    }
  }
}

GET t2_blogs_fixed2/_search # 에러 발생 코드
{
  &quot;query&quot;: {
    &quot;multi_match&quot;: {
      &quot;query&quot;: &quot;meetups&quot;,
      &quot;fields&quot;: [&quot;title&quot;, &quot;content&quot;]
    },
    &quot;range&quot;: {
      &quot;publish_date&quot;: {
        &quot;gte&quot;: &quot;now-3y&quot;
      }
    }
  }
}</code></pre><p><code>query</code> 내에 <code>multi_match</code>나 <code>range</code>가 하나씩 들어있을 때에는 둘 다 에러 없이 잘 실행됨
그런데 두개를 같이 넣으면 에러 발생
두 개 이상의 쿼리를 한 번에 쓰려면 <code>bool</code> 사용</p>
<pre><code>GET t2_blogs_fixed2/_search
{
  &quot;query&quot;: {
    &quot;bool&quot;: {
      &quot;must&quot;: [
        {
          &quot;multi_match&quot;: {
            &quot;query&quot;: &quot;meetups&quot;,
            &quot;fields&quot;: [&quot;title&quot;, &quot;content&quot;]
          }
        }
      ],
      &quot;filter&quot;: [
        {
          &quot;range&quot;: {
            &quot;publish_date&quot;: {
              &quot;gte&quot;: &quot;now-3y&quot;
            }
          }
        }
      ]
    }
  }
}</code></pre><p>위 코드에서 <code>range</code>가 <code>must</code> 내부에 작성되거나 <code>multi-match</code>가 <code>filter</code> 내부에 작성되어도 hits 수는 동일
다만, 검색어와 연관관계를 높이기 위해서 <code>multi-match</code>는 <code>must</code>에 작성하였고, 작성일자에 따라 그 연관성이 영향을 받는다고는 판단하지 않지만 기간이 명시되어 있었으므로 <code>filter</code>에 <code>range</code>를 작성함</p>
<hr>
<ol>
<li><code>content</code>에 <code>ingestion</code>이 포함되고</li>
<li><code>content</code>에 <code>logstash</code>가 포함되면 안 되며</li>
<li>프랑스어로 작성된 내용(<code>fr-fr</code>)을 검색<pre><code>GET t2_blogs_fixed2/_search
{
&quot;query&quot;: {
 &quot;bool&quot;: {
   &quot;must&quot;: [
     {
       &quot;match&quot;: {
         &quot;content&quot;: &quot;ingestion&quot; # ingestion을 포함
       }
     }
   ],
   &quot;must_not&quot;: [
     {
       &quot;match&quot;: {
         &quot;content&quot;: &quot;logstash&quot; # logstash를 미포함
       }
     }
   ], 
   &quot;filter&quot;: [
     {
       &quot;match&quot;: {
         &quot;locale&quot;: &quot;fr-fr&quot; # 프랑스어로 작성
       }
     }
   ]
 }
}
}</code></pre></li>
</ol>
<hr>
<pre><code>PUT _scripts/weekly_blogs
{
  &quot;script&quot;: {
    &quot;lang&quot;: &quot;mustache&quot;,
    &quot;source&quot;: {
      &quot;query&quot;: {
        &quot;bool&quot;: {
          &quot;filter&quot;: [
            {
              &quot;range&quot;: {
                &quot;publish_date&quot;: {
                  &quot;gte&quot;: &quot;{{start_date}}&quot;,
                  &quot;lte&quot;: &quot;{{start_date}}||+1w&quot;
                }
              }
            }
          ]
        }
      }
    }
  }
}</code></pre><p>3.3장 2번 문제
템플릿 작성할 때에는 자동완성이 도와주지 않기 때문에 실제로 쿼리를 작성하고 그 부분만 옮겨다 넣는 것이 편한 듯
삭제는 아래처럼 진행</p>
<pre><code>DELETE _scripts/weekly_blogs</code></pre><hr>
<p><code>pipeline</code> 작성할 때, <code>rename</code>이나 <code>remove</code>에 <code>ignore_missing</code> 옵션의 역할을 잘 모르겠음 =&gt; 공부 필요
<code>ignore_failure</code> 옵션이 존재하던데, 실패했을 때 그 실패를 무시하려면 사용하는 옵션이라고 생각됨
=&gt; <code>on_failure</code>를 설정하면 오류가 발생했을 때 어떻게 다룰지를 설정할 수 있음
<code>ignore_failure</code>를 따로 설정하지 않으면 dafault로 false인 것 같고, <code>on_failure</code>가 정의되어 있지 않아도 기본 처리방식이 있는 것으로 보임</p>
<hr>
<pre><code>GET t2_blogs_fixed2/_search
{
  &quot;size&quot;: 0,
  &quot;aggs&quot;: {
    &quot;NAME&quot;: {
      &quot;terms&quot;: {
        &quot;field&quot;: &quot;category&quot;
      }
    }
  }
}

POST categories/_bulk
{&quot;create&quot;:{}}
{&quot;uid&quot;: &quot;blt26ff0a1ade01f60d&quot;,&quot;title&quot;:&quot;User Stories&quot;}
{&quot;create&quot;:{}}
{&quot;uid&quot;: &quot;bltfaae4466058cc7d6&quot;,&quot;title&quot;: &quot;Releases&quot;}
{&quot;create&quot;:{}}
{&quot;uid&quot;: &quot;bltc253e0851420b088&quot;,&quot;title&quot;: &quot;Culture&quot;}
{&quot;create&quot;:{}}
{&quot;uid&quot;: &quot;blt0c9f31df4f2a7a2b&quot;,&quot;title&quot;: &quot;News&quot;}
{&quot;create&quot;:{}}
{&quot;uid&quot;: &quot;blt1d90b8e0edce3ea9&quot;,&quot;title&quot;: &quot;Engineering&quot;}

PUT _enrich/policy/t2_categories_policy
{
  &quot;match&quot;: {
    &quot;indices&quot;: &quot;categories&quot;,
    &quot;match_field&quot;: &quot;uid&quot;,
    &quot;enrich_fields&quot;: [&quot;title&quot;]
  }
}

POST _enrich/policy/t2_categories_policy/_execute</code></pre><p>순서대로 실행했을 때, 마지막에 enrich policy 실행하는 부분에서 런타임 에러가 발생... 왜?
그런데 이 정책으로 enrich 실행하는 자체는 잘 돌아갔음 뭘까 왤까
=&gt; 다음에 다시볼것</p>
<hr>
<pre><code># Request
GET t2_blogs_fixed2/_search
{
  &quot;size&quot;: 0,
  &quot;runtime_mappings&quot;: {
    &quot;authors.uid&quot;: {
      &quot;type&quot;: &quot;keyword&quot;
    }
  },
  &quot;aggs&quot;: {
    &quot;top_uids&quot;: {
      &quot;terms&quot;: {
        &quot;field&quot;: &quot;authors.uid&quot;
      }
    }
  }
}

# Response
{
  &quot;took&quot; : 488,
  &quot;timed_out&quot; : false,
  &quot;_shards&quot; : {
    &quot;total&quot; : 1,
    &quot;successful&quot; : 1,
    &quot;skipped&quot; : 0,
    &quot;failed&quot; : 0
  },
  &quot;hits&quot; : {
    &quot;total&quot; : {
      &quot;value&quot; : 4659,
      &quot;relation&quot; : &quot;eq&quot;
    },
    &quot;max_score&quot; : null,
    &quot;hits&quot; : [ ]
  },
  &quot;aggregations&quot; : {
    &quot;top_uids&quot; : {
      &quot;doc_count_error_upper_bound&quot; : 0,
      &quot;sum_other_doc_count&quot; : 4722,
      &quot;buckets&quot; : [
      ....
      ...
      ...

}</code></pre><p>전체 자료 개수는 4659개
<code>authors.uid</code>라는 필드를 런타임 동안에 작성하였지만 내용이 아무것도 없을 것이기 때문에 aggregation이 진행되는 것은 하나도 없을 것으로 예상
=&gt; 전체 조회와 동일하게 4659개의 bucket이 나오는 것이 맞다고 생각함
그런데 결과에서 보이는 <code>sum_other_doc_count</code>가 4722개
이게 뭘까?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230424] module 1~2 실습 기록]]></title>
            <link>https://velog.io/@jyo____c/230424-TIL</link>
            <guid>https://velog.io/@jyo____c/230424-TIL</guid>
            <pubDate>Mon, 24 Apr 2023 05:44:02 GMT</pubDate>
            <description><![CDATA[<pre><code>PUT blogs_test
{
  &quot;settings&quot;: {
    &quot;analysis&quot;: {
      &quot;char_filter&quot;: {
        &quot;my_filter&quot;: {
          &quot;type&quot;: &quot;mapping&quot;,
          &quot;mappings&quot;: [&quot;X-Pack =&gt; XPack&quot;]
        }
      },
      &quot;analyzer&quot;: {
        &quot;my_content_analyzer&quot;: {
          &quot;type&quot;: &quot;custom&quot;,
          &quot;tokenizer&quot;: &quot;standard&quot;,
          &quot;filter&quot;: [&quot;lowercase&quot;],
          &quot;char_filter&quot;: [&quot;my_filter&quot;]
        }
      }
    }
  },
  &quot;mappings&quot;: {
    &quot;properties&quot;: {
      &quot;content&quot;: {
        &quot;type&quot;: &quot;text&quot;,
        &quot;analyzer&quot;: &quot;my_content_analyzer&quot;
      }
    }
  }
}

POST blogs_test/_analyze
{
 &quot;text&quot;: [&quot;We love X-Pack&quot;],
 &quot;analyzer&quot;: &quot;my_content_analyzer&quot;
}

POST blogs_test/_doc
{
  &quot;content&quot;: &quot;We love X-Pack&quot;
}</code></pre><p>mapping에서 분석기 만들어놓고, 필드 타입이랑 분석기를 지정해 줬는데도 document를 넣으면 keyword랑 다를 바 없이 &quot;We love X-Pack&quot;가 그대로 저장되는 것을 확인
=&gt; 우리한테 보여줄 때에는 그렇게 보이고, analysis는 내부적으로 실행되어 그 결과는 따로 가지고 있는 것!
그래서 어떻게 분석되는지 확인할 때 쓰는 것이 &quot;_analyze&quot; API</p>
<hr>
<pre><code>PUT 인덱스이름 # 아무것도 없는 빈 인덱스 생성

PUT 인덱스이름/_mapping # 빈 인덱스에 매핑 추가 가능</code></pre><pre><code>PUT 인덱스이름 # 위 두 번의 요청과 이 한 번의 요청은 동일한 결과
{
    &quot;mapping&quot;: {
        ...
    }
}</code></pre><hr>
<p>새 인덱스로 reindex</p>
<pre><code>POST _reindex
{
    &quot;source&quot;: {
        &quot;index&quot;: &quot;원본 인덱스&quot;
    },
    &quot;dest&quot;: {
        &quot;index&quot;: &quot;목표 인덱스&quot;
    }
}</code></pre><hr>
<p>인덱스 내 document 개수 확인</p>
<pre><code>GET 인덱스이름/_count</code></pre><hr>
<p>HTML 태그 제거하는 <code>char_filter</code>는 <code>html_strip</code></p>
<hr>
<p>query나 aggregation에 사용하지 않을 필드는 <code>doc_values</code>를 <code>false</code>로 해두면 저장공간을 절약할 수 있음</p>
<pre><code>PUT 인덱스이름
{
    &quot;mappings&quot;: {
        &quot;properties&quot;: {
            &quot;필드명&quot;: {
                &quot;doc_values&quot;: false
            }
        }
    }
}</code></pre><hr>
<p>실습 페이지 Lab 2.4의 1번 solution 결과로 <code>_search</code> 했을 때 <code>search_tags</code>에 <code>tags</code>의 모든 필드가 나오지 않는 점이 의문
=&gt; document를 indexing할 때 설정하지 않은 필드는 결과에서도 보여주지 않기 때문
빈 배열로 나오는 필드는 빈 배열이 indexing할 때 값으로 있었던 것</p>
<hr>
<p><code>&quot;doc_values&quot;: false</code>와 <code>&quot;enabled&quot;: false</code>는 모두 query와 aggregation에 사용할 수 없음
=&gt; 그럼 왜 두 개의 약속어가 존재하는지 의문</p>
<p>doc_values: false</p>
<ul>
<li>query, aggregation에 사용할 수 없음 (오류 발생)</li>
<li>필드에 대한 검색은 가능</li>
</ul>
<p>enabled: false</p>
<ul>
<li>query, aggregation에 사용할 수 없음 (결과값이 0)</li>
<li>object type에 사용하며, 상위 필드에서 선언하면 그 하위 필드들까지 모두 enabled가 false로 설정됨</li>
<li>현재는 사용하지 않는 옵션</li>
</ul>
<p>(추가)
index: false</p>
<ul>
<li>query, aggregation에 사용할 수 없음</li>
<li>필드에 대한 검색도 불가능</li>
<li>enabled 대신 사용 가능</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230421] 실습 내용 정리]]></title>
            <link>https://velog.io/@jyo____c/230421-TIL</link>
            <guid>https://velog.io/@jyo____c/230421-TIL</guid>
            <pubDate>Mon, 24 Apr 2023 00:26:09 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-elastic"># Request
GET _analyze
{
    # &quot;analyzer&quot;: &quot;english&quot;, &lt;- 분석기 명시 가능. 생략하면 default
    &quot;text&quot;: &quot;Tuning Go Apps in a Beat 123&quot;
}</code></pre>
<pre><code class="language-elastic"># Response
{
    &quot;tokens&quot;:
    [
        {
            &quot;token&quot;: &quot;tuning&quot;,
            &quot;start_offset&quot;: 0,
            &quot;end_offset&quot;: 6,
            &quot;type&quot;: &quot;&lt;ALPHANUM&gt;&quot;,
            &quot;position&quot;: 0
        },
        {...},
        ...
        {
            &quot;token&quot;: &quot;123&quot;, # NUM 타입인데 왜 문자열처럼 &quot;&quot;으로 감싸져 나올까
            &quot;start_offset&quot;: 25,
            &quot;end_offset&quot;: 28,
            &quot;type&quot;: &quot;&lt;NUM&gt;&quot;,
            &quot;position&quot;: 6
        }
    ]
}</code></pre>
<hr>
<pre><code># analyzer 설정
PUT blogs_test
{
  &quot;settings&quot;: {
    &quot;analysis&quot;: { # 분석 관련된 내용을 정의하는 곳
      &quot;char_filter&quot;: { # 문자에 대한 필터를 작성하겠다고 선언
        &quot;my_filter&quot;: {
          &quot;type&quot;: &quot;mapping&quot;,
          &quot;mappings&quot;: [&quot;X-Pack =&gt; XPack&quot;]
        }
      },
      &quot;analyzer&quot;: { # 사용할 분석기에 대한 설정
        &quot;my_content_analyzer&quot;: {
        # 이 안에 순서를 바꿔봤는데, 결과가 달라지진 않았음
        # 내부 순서가 적용되는 순서에 영향을 미치지는 않는 듯
          &quot;type&quot;: &quot;custom&quot;, # 존재하는 규칙 사용하지 않겠다고 명시
          &quot;char_filter&quot;: [&quot;my_filter&quot;], # 문자열 필터에 위에서 정의한 필터 가져옴
          &quot;tokenizer&quot;: &quot;standard&quot;, # 기본 방법으로 토큰 구별
          &quot;filter&quot;: [&quot;lowercase&quot;] # 이후 모두 소문자로 변경
        }
      }
    }
  }
}</code></pre><pre><code># Request
POST blogs_test/_analyze #blogs_test
{
  &quot;text&quot;: &quot;We love X-Pack&quot;,
  &quot;analyzer&quot;: &quot;my_content_analyzer&quot;
}</code></pre><pre><code># Response
{
  &quot;tokens&quot;: [
    {
      &quot;token&quot;: &quot;we&quot;,
      &quot;start_offset&quot;: 0,
      &quot;end_offset&quot;: 2,
      &quot;type&quot;: &quot;&lt;ALPHANUM&gt;&quot;,
      &quot;position&quot;: 0
    },
    {
      &quot;token&quot;: &quot;love&quot;,
      &quot;start_offset&quot;: 3,
      &quot;end_offset&quot;: 7,
      &quot;type&quot;: &quot;&lt;ALPHANUM&gt;&quot;,
      &quot;position&quot;: 1
    },
    {
      &quot;token&quot;: &quot;xpack&quot;,
      &quot;start_offset&quot;: 8,
      &quot;end_offset&quot;: 14,
      &quot;type&quot;: &quot;&lt;ALPHANUM&gt;&quot;,
      &quot;position&quot;: 2
    }
  ]
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[230420] Elastic Stack 3일차 리뷰 내용]]></title>
            <link>https://velog.io/@jyo____c/230420-TIL</link>
            <guid>https://velog.io/@jyo____c/230420-TIL</guid>
            <pubDate>Fri, 21 Apr 2023 01:22:55 GMT</pubDate>
            <description><![CDATA[<h2 id="개념-추가">개념 추가</h2>
<p>클러스터, 노드는 논리적인 개념이지 물리적인 개념이 아님
한 서버에 노드를 여러 개 올릴 수 있지만 서버 스펙이 좋아도 하나만 올릴 것이 권장됨
=&gt; 디스크를 공유하는 데에 있어서 속도가 영향을 받음</p>
<h2 id="shard">Shard</h2>
<p>샤드는 Lucene의 한 인스턴스이다 = 샤드 하나하나가 모두 검색 엔진이다
하나당 20GB를 넘어가지 않도록 구성해야 함</p>
<h3 id="replica-shard를-유지하는-이유">replica shard를 유지하는 이유</h3>
<ul>
<li>여러 노드에 분산 저장하여 검색, 색인을 병렬화 =&gt; 속도 향상</li>
<li>노드 하나에 문제가 생겼을 때, 사본을 가지고 있는 다른 노드로 인해 장애 없이 유지 가능</li>
<li>primary shard가 손실되면 replica 중 하나가 primary로 승격되어 유지</li>
</ul>
<h2 id="shard-overallocation">Shard overallocation</h2>
<h3 id="static-data">static data</h3>
<p>샤드의 수를 넉넉하게 잡아놓고 읽기/쓰기 작업에 대한 병렬화를 진행
=&gt; overallocation</p>
<h3 id="time-series-data">time-series data</h3>
<p>분산하여 저장해놓고 따로 쓰거나 따로 읽거나 할 일이 거의 없음
단위별로 인덱스를 따로 만드는 편이 더 유용함
=&gt; overallocation보다는 multiple indices가 적합</p>
<h2 id="filter">filter</h2>
<p>필터는 캐시에 올라가 있는 데이터를 활용하기 때문에 속도가 빠름
=&gt; 사용 권장!</p>
<h2 id="indexrefresh_interval">index.refresh_interval</h2>
<p><code>index.refresh_interval</code>은 document가 indexing된 후 검색에 반영되기까지 걸리는 시간
-1로 설정하는 경우, indexing이 진행되는 동안 반영되지 않다가 작업이 종료되면 default 설정으로 돌아감
길게 설정하면 indexing 속도는 빨라지지만 검색에 반영되려면 오래 기다려야 함</p>
<h2 id="data-stream">Data stream</h2>
<p>aliases와 거의 유사하나 그보다 한 단계 더 자동화 되어있음</p>
<h3 id="backing-indices">backing indices</h3>
<p>data stream은 여러 인덱스로 구성된 개념
이 중에 실제로 write 작업이 수행되는 인덱스는 하나만 존재
이 write가 수행되는 인덱스 이외의 인덱스들을 <code>backing indices</code>라고 함</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230419] Elastic Stack 2일차 리뷰 내용]]></title>
            <link>https://velog.io/@jyo____c/230419-TIL</link>
            <guid>https://velog.io/@jyo____c/230419-TIL</guid>
            <pubDate>Thu, 20 Apr 2023 00:11:22 GMT</pubDate>
            <description><![CDATA[<h2 id="async-search">Async search</h2>
<p>오래 걸리는 query나 aggregation에 대해</p>
<ol>
<li>진행 상황을 모니터링 하거나</li>
<li>부분적인 결과 상황을 확인할 때 사용</li>
</ol>
<h2 id="changing-data">Changing data</h2>
<h3 id="reindex">Reindex</h3>
<p>원본 index가 있고, 그 인덱스에서 파생된 사본을 만드는 것
전체 document를 대상으로 하지 않고 일부만을 활용하고 싶을 때에는
<code>max_docs</code> 나 <code>query</code>를 활용할 수 있음
한 클러스터에서 다른 클러스터로의 인덱스 복제도 가능</p>
<h3 id="update-by-query">Update by Query</h3>
<p>한 index 내에서 document를 수정하는 것
내용 수정 -&gt; 저장 (x)
삭제 -&gt; 재등록 (o)
=&gt; document가 등록된 이후 indexing 절차가 달라졌을 수도 있기 때문에, 이런 내용을 반영하기 위해서 삭제했다가 다시 재등록하는 과정을 거침</p>
<h2 id="enrichment">Enrichment</h2>
<p>RDB의 join과 유사한 개념
검색이 이루어질 때 join이 발생하면 데이터를 처리하는 과정이 추가되는 것이므로 속도가 느려질 수 있음
그래서 애초에 document가 indexing될 때, 필요한 내용을 다 끌어오는 것을 <code>enrich</code>라고 함</p>
<h3 id="denormalization">Denormalization</h3>
<p>데이터를 저장할 때, 관계성에 중점을 두지 않고 하나의 index에 가능한 모든 정보를 담아두는 것
Elasticsearch의 외부에서 혹은 내부에서 모두 가능하지만, 내부에서 이루어지면 당연히 처리하는 과정이 추가되므로 속도에 영향을 줌
=&gt; 외부에서 처리를 마치고 오는 것이 이상적</p>
<h2 id="runtime-fields">Runtime fields</h2>
<p>index에는 존재하지 않지만 query를 실행하는 순간 생성되어 search, aggregation 등의 작업이 가능한 필드
실행되어 결과를 보여주고 난 이후에는 다시 사라짐 (저장되지 않음)</p>
<h3 id="painless-script">Painless script</h3>
<p>요청을 수행할 때 작업할 추가적인 내용들을 작성하기 위한 Elasticsearch의 언어
작업 중에 수행되므로 작업의 속도를 늦출 수 있음
임시 방편으로, 가능하면 사용하지 않고 reindexing하거나 update하는 것이 좋음</p>
<h2 id="significant-aggregation">Significant aggregation</h2>
<p>필드의 타입에 따라 두 가지 옵션이 존재</p>
<ul>
<li><code>significant_terms</code> : keyword 필드에 사용</li>
<li><code>significant_text</code> : text 필드에 사용</li>
</ul>
<p>대량의 문서 내에서 작업하기 힘들 수 있으므로 표본을 만들 수 있는 sampler aggregation을 진행한 후, 그 내부에서 사용하기가 권장됨</p>
<h2 id="transforming-data">Transforming data</h2>
<p>대량의 데이터에서 매번 정보를 요약해오는 것은 부담이 될 수 있는 작업
=&gt; 요약본을 미리 마련해두어 별도의 index에 유지하는 것이 transform</p>
<h3 id="pivot">pivot</h3>
<p>transform의 종류 중 하나
원본 테이블에 대해 필요한 정보를 어떻게 요약할지 정의하여 유지</p>
<h4 id="continuous-mode">Continuous mode</h4>
<p>원본 index에 document가 들어올 때, pivot에도 해당 document에 대한 정보가 들어옴
원본 index를 체크하는 시간 주기를 설정 가능 (최대 1시간)</p>
<h4 id="retention-policy">Retention policy</h4>
<p>오래된 document에 대한 내용을 어떻게 처리할지 설정 가능</p>
<h3 id="latest">Latest</h3>
<p>최신 내용만 가지고 있으면 되는 경우에 선택할 수 있는 transform 종류
새로은 document가 들어오면 기존 내용 대신 해당 내용을 보관하게 됨</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[230418] Elastic Stack 1일차 리뷰 내용]]></title>
            <link>https://velog.io/@jyo____c/230418-TIL</link>
            <guid>https://velog.io/@jyo____c/230418-TIL</guid>
            <pubDate>Wed, 19 Apr 2023 00:19:28 GMT</pubDate>
            <description><![CDATA[<p>Elastic Search는 검색, 분석을 위한 엔진</p>
<h4 id="기본-개념">기본 개념</h4>
<p>맨 꼭대기에 있는 cluster, 그 아래로 각 실행흐름인 node, 그 아래 RDB의 테이블과 비슷한 개념으로 생각할 수 있는 index가 존재</p>
<p>클러스터는 여러 개가 존재할 수 있으며, 각 클러스터가 논리적으로 분리됨
클러스터끼리 데이터를 주고 받는 식으로 통신이 가능</p>
<p>클러스터 아래에 노드는 여러 개가 달려있을 수 있음
노드는 하나의 Instance라고 부름</p>
<p>노드 아래에 존재하는 개념인 인덱스는 테이블과 유사하다고 볼 수 있음
DB에는 Insert를 한다면, Index에는 Indexing을 함
DB의 row는 Index의 document</p>
<h4 id="엘라스틱의-데이터-구분">엘라스틱의 데이터 구분</h4>
<h5 id="static-data">Static data</h5>
<ul>
<li>증량은 적고, 그에 비해 업데이트가 잦은 데이터</li>
<li>코드성 테이블</li>
<li>정형화된 데이터에 적합</li>
</ul>
<h5 id="time-series-data">Time series data</h5>
<ul>
<li>업데이트는 거의 없지만, 증량이 빠른 데이터</li>
<li>log와 같이 insert가 계속 되는 것</li>
</ul>
<h4 id="query-option">Query option</h4>
<ul>
<li>Lucene(루씬)
Elastic Search의 기반이 되는 검색 엔진</li>
<li>Query DSL
Elastick Search에서 가장 유연하게 사용할 수 있는 query</li>
</ul>
<h4 id="keyword-vs-text">Keyword vs text</h4>
<p>Text</p>
<ul>
<li>인덱싱이 발생하는, 필드의 데이터 타입</li>
<li>원본 문자열을 가공하기 때문에 검색이 필요한 경우 적합</li>
</ul>
<p>Keyword</p>
<ul>
<li>인덱싱이 발생하지 않는 원본 문자열</li>
<li>aggregation을 위해 사용하는 경우가 많음</li>
</ul>
<h4 id="mapping">mapping</h4>
<p>RDB에서 테이블을 정의하는 것과 같은 동작
mapping은 index를 정의함 = index의 스키마를 정하는 것이 mapping</p>
<h4 id="dynamic-templates">dynamic templates</h4>
<p>정의되지 않은 필드에 document를 인덱싱하려고 하면 Elastic Search는 동적으로 매핑을 진행해줌 (그다지 권장되지는 않음)
이 때, 동적으로 매핑이 발생하더라도 그에 대한 어느 정도의 기반을 마련해 주는 것이 dynamic templates
정의하지 않아도 dynamic mapping은 발생하지만, 정의된 틀에 맞는 경우에는 어느 정도 대비할 수 있게 됨</p>
<h4 id="score">Score</h4>
<ul>
<li>score : 조건에 맞는 결과들에 점수를 매겨 <code>유사도</code> 혹은 <code>유용도</code>를 수치화한 것</li>
<li>Elastic Search는 default로 BM25 알고리즘을 사용하여 score를 매김</li>
<li>score의 3요소<ul>
<li>TF(term frequency)<ul>
<li>검색한 단어가 나타나는 빈도가 높다면 점수를 높게 계산</li>
<li>하나의 문서 내에서 적용하는 규칙</li>
</ul>
</li>
<li>IDF(inverse document frequency)<ul>
<li>검색한 단어가 나타나는 빈도가 높다면 점수를 낮게 계산</li>
<li>여러 개의 문서에 대해서 적용하는 규칙</li>
</ul>
</li>
<li>field length<ul>
<li>더 짧은 필드에 대해 더 높은 점수를 부여</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>