elasticsearch 기초 - Field Collapsing 필드 축소

23004 단어 ELKelasticsearch
필드 값에 따라 검색 결과를 축소할 수 있습니다.축소 버튼을 눌러 문서 정렬의 맨 위를 선택하여 축소를 완료합니다.예를 들어 아래의 검색은 모든 사용자의 가장 좋은 추문을 검색하고 좋아하는 수량에 따라 정렬합니다.
GET /twitter/_search
{
    "query": {
        "match": {
            "message": "elasticsearch"
        }
    },
    "collapse" : {
        "field" : "user" ①
    },
    "sort": ["likes"],  ②
    "from": 10  ③
}

사용자 필드를 사용하여 결과 세트 축소
원하는 수량에 따라 최상위 문서 정렬
첫 번째 축소 결과의 오프셋 정의하기
응답의 총 적중량은 축소된 일치하는 문서가 없음을 나타냅니다.다른 그룹의 총수는 알 수 없습니다.
축소용 필드는 keyword 또는 numeric doc_ 활성화되어 있어야 합니다.values 필드
축소는 상단 일치에만 적용되며 집합에는 영향을 주지 않습니다.

Expand collapse result


inner_ 를 사용할 수도 있습니다hits 옵션은 접힌 모든 상단 명중을 펼칩니다.
GET /twitter/_search
{
    "query": {
        "match": {
            "message": "elasticsearch"
        }
    },
    "collapse" : {
        "field" : "user", ①
        "inner_hits": {
            "name": "last_tweets", ②
            "size": 5, ③
            "sort": [{ "date": "asc" }]  ④
        },
        "max_concurrent_group_searches": 4  ⑤
    },
    "sort": ["likes"]
}

사용자 필드를 사용하여 결과 세트 축소
응답의 내부 적중력 부분에 대한 이름
접는 키마다 읽어들이는 inner_히트 수
각 그룹 내의 문서를 정렬하는 방법
그룹당 inner_ 검색 허용hits`의 병렬 요청 수
지원되는 옵션의 전체 목록과 응답 형식은 내부 적중력을 참조하십시오.inner_hits 접을 때마다 적중력을 여러 개 요청할 수 있습니다.이것은 접기 적중의 여러 표시를 얻으려고 할 때 유용할 수 있습니다.
GET /twitter/_search
{
    "query": {
        "match": {
            "message": "elasticsearch"
        }
    },
    "collapse" : {
        "field" : "user",  ①
        "inner_hits": [
            {
                "name": "most_liked",  
                "size": 3, ②
                "sort": ["likes"]
            },
            {
                "name": "most_recent", 
                "size": 3, ③
                "sort": [{ "date": "asc" }]
            }
        ]
    },
    "sort": ["likes"]
}

사용자 필드를 사용하여 결과 세트 축소
사용자가 가장 좋아하는 세 개의 트윗으로 되돌아가다
사용자에게 돌아가는 세 가지 최신 트윗inner_hit 응답에서 되돌아오는 접힌 명중의 요청마다 추가 조회를 보내서 그룹의 확장을 완성합니다.그룹 및/또는 inner_hit 요청이 너무 많으면 속도가 크게 느려질 수 있습니다.
상기 max_concurrent_group_searches 요청 매개 변수는 이 단계에서 병행 검색을 허용하는 최대 수를 제어하는 데 사용할 수 있습니다.기본값은 데이터 노드 수와 기본 검색 스레드 탱크 크기를 기반으로 합니다.collapse 스크롤, 재결합 또는 검색과 함께 사용할 수 없음

두 번째 레벨 of collapsing 2단계 축소


2단계 축소inner_hits도 지원됩니다.예를 들어, 다음 요청은 각 국가의 최고 득점 트윗을 찾고 각 국가의 최고 득점 트윗을 찾습니다.
2단계 축소는 허용되지 않음inner_hits
GET /twitter/_search
{
    "query": {
        "match": {
            "message": "elasticsearch"
        }
    },
    "collapse" : {
        "field" : "country",
        "inner_hits" : {
            "name": "by_location",
            "collapse" : {"field" : "user"},
            "size": 3
        }
    }
}

응답:
{
    ...
    "hits": [
        {
            "_index": "twitter",
            "_type": "_doc",
            "_id": "9",
            "_score": ...,
            "_source": {...},
            "fields": {"country": ["UK"]},
            "inner_hits":{
                "by_location": {
                    "hits": {
                       ...,
                       "hits": [
                          {
                            ...
                            "fields": {"user" : ["user124"]}
                          },
                          {
                            ...
                            "fields": {"user" : ["user589"]}
                          },
                          {
                            ...
                             "fields": {"user" : ["user001"]}
                          }
                       ]
                    }
                 }
            }
        },
        {
            "_index": "twitter",
            "_type": "_doc",
            "_id": "1",
            "_score": ..,
            "_source": {...},
            "fields": {"country": ["Canada"]},
            "inner_hits":{
                "by_location": {
                    "hits": {
                       ...,
                       "hits": [
                          {
                            ...
                            "fields": {"user" : ["user444"]}
                          },
                          {
                            ...
                            "fields": {"user" : ["user1111"]}
                          },
                          {
                            ...
                             "fields": {"user" : ["user999"]}
                          }
                       ]
                    }
                 }
            }

        },
        ....
    ]
}

인스턴스


다음은 구체적인 예를 보면 어떻게 된 일인지 알 수 있고 사용하기에 매우 간단하다.
  • 먼저 인덱스와 데이터를 준비합니다. 여기서 레시피를 예로 들면name: 레시피 이름, type 메뉴, rating 사용자의 누적 평균 평점
  • PUT recipes
    POST /recipes/type/_mapping
    {
      "properties": {
        "name":{
          "type": "text"
        },
        "rating":{
          "type": "float"
        },"type":{
          "type": "keyword"
        }
      }
    }
    /recipes/_bulk
    { "index":  { "_index": "recipes", "_type": "type"}}
    {"name":" ","rating":1,"type":" "}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":" ","rating":2,"type":" "}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":" ","rating":3,"type":" "}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":" ( )","rating":3,"type":" "}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":" ( )","rating":4,"type":" "}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":" ( )","rating":5,"type":" "}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":" ","rating":5,"type":" "}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":" ","rating":2,"type":" "}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":" ","rating":2,"type":" "}
  • 이제 일반적인 검색 효과가 어떤지 봅시다. 키워드에'물고기'가 들어간 요리를 검색해서 데이터 3개를 되돌려줍니다
  • POST recipes/type/_search
    {
      "query": {"match": {
        "name": " "
      }},"size": 3
    } 
    

    모두 샹차이입니다. 세상에. 요즘 화가 나서 맵고 싶지 않아요. 이 첫 페이지의 결과는 저에게 쓰레기입니다. 아래와 같습니다.
    {
      "took": 2,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": 0.26742277,
        "hits": [
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHYF_OA-dG63Txsd",
            "_score": 0.26742277,
            "_source": {
              "name": " ( )",
              "rating": 5,
              "type": " "
            }
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHXO_OA-dG63Txsa",
            "_score": 0.19100356,
            "_source": {
              "name": " ",
              "rating": 3,
              "type": " "
            }
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHWy_OA-dG63TxsZ",
            "_score": 0.19100356,
            "_source": {
              "name": " ",
              "rating": 2,
              "type": " "
            }
          }
        ]
      }
    }
    
  • 다시 한 번 봅시다. 이번에 저는 평점 순위를 붙이고 싶습니다. 모두가 좋아하는 것은 그것입니다. 좋아하는 음식이 있는지 알아보고 조회를 실행합니다.
  • POST recipes/type/_search
    {
      "query": {"match": {
        "name": " "
      }},"sort": [
        {
          "rating": {
            "order": "desc"
          }
        }
      ],"size": 3
    } 
    

    결과는 좀 나아졌지만 3개 중 2개가 샹차이인지 좀 안 맞았는데 결과는 다음과 같다.
    {
      "took": 1,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": null,
        "hits": [
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHYF_OA-dG63Txsd",
            "_score": null,
            "_source": {
              "name": " ( )",
              "rating": 5,
              "type": " "
            },
            "sort": [
              5
            ]
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHYW_OA-dG63Txse",
            "_score": null,
            "_source": {
              "name": " ",
              "rating": 5,
              "type": " "
            },
            "sort": [
              5
            ]
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHX7_OA-dG63Txsc",
            "_score": null,
            "_source": {
              "name": " ( )",
              "rating": 4,
              "type": " "
            },
            "sort": [
              4
            ]
          }
        ]
      }
    }
    
  • 이제 알았어요. 다른 메뉴를 봐야겠어요. 이 집에는 양식, 광동요리 등 여러 가지 요리가 있잖아요. 자, 요리마다 한 가지 요리를 만들어 주세요.hitsagg, 평점에 따라 정렬된 첫 번째 tophits를 되돌려줍니다. 좀 복잡합니다. 괜찮습니다. 아래의 조회를 보면 알 수 있습니다.
  • GET recipes/type/_search
    {
      "query": {
        "match": {
          "name": " "
        }
      },
      "sort": [
        {
          "rating": {
            "order": "desc"
          }
        }
      ],"aggs": {
        "type": {
          "terms": {
            "field": "type",
            "size": 10
          },"aggs": {
            "rated": {
              "top_hits": {
                "sort": [{
                  "rating": {"order": "desc"}
                }], 
                "size": 1
              }
            }
          }
        }
      }, 
      "size": 0,
      "from": 0
    } 
    

    아래의 결과를 보면 json의 구조가 좀 복잡하지만 드디어 우리가 원하는 결과이다. 샹차이, 광둥요리, 사천요리, 서양요리가 모두 나왔다. 하나하나가 똑같지 않다.
    {
      "took": 4,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": 0,
        "hits": []
      },
      "aggregations": {
        "type": {
          "doc_count_error_upper_bound": 0,
          "sum_other_doc_count": 0,
          "buckets": [
            {
              "key": " ",
              "doc_count": 6,
              "rated": {
                "hits": {
                  "total": 6,
                  "max_score": null,
                  "hits": [
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHYF_OA-dG63Txsd",
                      "_score": null,
                      "_source": {
                        "name": " ( )",
                        "rating": 5,
                        "type": " "
                      },
                      "sort": [
                        5
                      ]
                    }
                  ]
                }
              }
            },
            {
              "key": " ",
              "doc_count": 1,
              "rated": {
                "hits": {
                  "total": 1,
                  "max_score": null,
                  "hits": [
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHYr_OA-dG63Txsf",
                      "_score": null,
                      "_source": {
                        "name": " ",
                        "rating": 2,
                        "type": " "
                      },
                      "sort": [
                        2
                      ]
                    }
                  ]
                }
              }
            },
            {
              "key": " ",
              "doc_count": 1,
              "rated": {
                "hits": {
                  "total": 1,
                  "max_score": null,
                  "hits": [
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHYW_OA-dG63Txse",
                      "_score": null,
                      "_source": {
                        "name": " ",
                        "rating": 5,
                        "type": " "
                      },
                      "sort": [
                        5
                      ]
                    }
                  ]
                }
              }
            },
            {
              "key": " ",
              "doc_count": 1,
              "rated": {
                "hits": {
                  "total": 1,
                  "max_score": null,
                  "hits": [
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHY3_OA-dG63Txsg",
                      "_score": null,
                      "_source": {
                        "name": " ",
                        "rating": 2,
                        "type": " "
                      },
                      "sort": [
                        2
                      ]
                    }
                  ]
                }
              }
            }
          ]
        }
      }
    }
    
  • 위의 실현 방법은 앞에서 말했듯이 할 수 있고 한계가 있다. 그러면 새로운 필드 접기법을 어떻게 하는지 보자. 아래와 같이collapse 파라미터를 추가하여 그 필드를 다시 그리도록 지정하면 된다. 여기는 당연히 메뉴'type'필드를 무겁게 한다.
  • GET recipes/type/_search
    {
      "query": {
        "match": {
          "name": " "
        }
      },
      "collapse": {
        "field": "type"
      },
      "size": 3,
      "from": 0
    }
    

    결과는 이상적이야. 명중 결과는 익숙한 그 맛이야.
    {
      "took": 1,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": null,
        "hits": [
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoDNlRJ_OA-dG63TxpW",
            "_score": 0.018980097,
            "_source": {
              "name": " ( )",
              "rating": 4,
              "type": " "
            },
            "fields": {
              "type": [
                " "
              ]
            }
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoDNlRk_OA-dG63TxpZ",
            "_score": 0.013813315,
            "_source": {
              "name": " ",
              "rating": 2,
              "type": " "
            },
            "fields": {
              "type": [
                " "
              ]
            }
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoDNlRb_OA-dG63TxpY",
            "_score": 0.0125863515,
            "_source": {
              "name": " ",
              "rating": 5,
              "type": " "
            },
            "fields": {
              "type": [
                " "
              ]
            }
          }
        ]
      }
    }
    
  • 다시 한 번 페이지를 넘기고from을 고쳐 보겠습니다. 현재 3개의 데이터가 돌아왔습니다.from을 3으로 바꾸었습니다. 새로운 조회는 다음과 같습니다.
  • {
      "took": 1,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": null,
        "hits": [
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoDNlRw_OA-dG63Txpa",
            "_score": 0.012546891,
            "_source": {
              "name": " ",
              "rating": 2,
              "type": " "
            },
            "fields": {
              "type": [
                " "
              ]
            }
          }
        ]
      }
    }
    
  • 위의 결과는 하나밖에 없어요. 중량을 제거한 후에 원래 4개의 데이터만 있어요. 위의 작업은 정상이고 요리는 하나밖에 없어요. 그럼 싫어요. 요리마다 몇 개를 더 돌려주세요. 제가 요리를 선택할 수 있어요. 파라미터 inner_hits는 되돌아오는 줄의 수를 제어합니다. 여기는 두 줄로 되돌아오고rating에 따라 순서를 정합니다. 새로운 조회 구조는 다음과 같습니다.
  • GET recipes/type/_search
    {
      "query": {
        "match": {
          "name": " "
        }
      },
      "collapse": {
        "field": "type",
        "inner_hits": {
          "name": "top_rated",
          "size": 2,
          "sort": [
            {
              "rating": "desc"
            }
          ]
        }
      },
      "sort": [
        {
          "rating": {
            "order": "desc"
          }
        }
      ],
      "size": 2,
      "from": 0
    }
    

    검색 결과는 다음과 같습니다.
    {
      "took": 1,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": null,
        "hits": [
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHYF_OA-dG63Txsd",
            "_score": null,
            "_source": {
              "name": " ( )",
              "rating": 5,
              "type": " "
            },
            "fields": {
              "type": [
                " "
              ]
            },
            "sort": [
              5
            ],
            "inner_hits": {
              "top_rated": {
                "hits": {
                  "total": 6,
                  "max_score": null,
                  "hits": [
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHYF_OA-dG63Txsd",
                      "_score": null,
                      "_source": {
                        "name": " ( )",
                        "rating": 5,
                        "type": " "
                      },
                      "sort": [
                        5
                      ]
                    },
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHX7_OA-dG63Txsc",
                      "_score": null,
                      "_source": {
                        "name": " ( )",
                        "rating": 4,
                        "type": " "
                      },
                      "sort": [
                        4
                      ]
                    }
                  ]
                }
              }
            }
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHYW_OA-dG63Txse",
            "_score": null,
            "_source": {
              "name": " ",
              "rating": 5,
              "type": " "
            },
            "fields": {
              "type": [
                " "
              ]
            },
            "sort": [
              5
            ],
            "inner_hits": {
              "top_rated": {
                "hits": {
                  "total": 1,
                  "max_score": null,
                  "hits": [
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHYW_OA-dG63Txse",
                      "_score": null,
                      "_source": {
                        "name": " ",
                        "rating": 5,
                        "type": " "
                      },
                      "sort": [
                        5
                      ]
                    }
                  ]
                }
              }
            }
          }
        ]
      }
    }
    

    자, 필드 접기 소개는 여기까지.

    좋은 웹페이지 즐겨찾기