본문 바로가기
WIKI 기술 지식 베이스

Radial search

원문 보기 위키 갱신

출처: 문서

본문

방사형 검색

방사형 검색은 근사 top-k 검색을 넘어 벡터 검색 기능을 확장해요. 방사형 검색을 사용하면 벡터 공간 안에서 쿼리 포인트로부터 지정한 최대 거리 이내에 있거나 최소 점수 임계값 이상인 모든 포인트를 검색할 수 있어요. 이를 통해 검색 작업의 유연성과 활용도가 한층 높아져요.

방사형 검색은 Lucene 엔진이나 Faiss 엔진 중 하나를 사용해 수행할 수 있어요. 두 엔진 모두 중첩 필드에 대한 방사형 검색을 지원해요.

파라미터

방사형 검색은 다음 파라미터를 지원해요:

  • max_distance: 벡터 공간 안의 물리적 거리를 지정해요. 쿼리 포인트에서 이 거리 이내에 있는 모든 포인트를 식별하죠. 이 방식은 공간적 근접성이나 절대 거리 측정이 필요한 애플리케이션에 특히 유용해요.

min_score: 유사도 점수를 지정해요. 쿼리 포인트와 비교했을 때 이 점수 이상을 충족하는 포인트를 손쉽게 찾아낼 수 있죠. 이 방식은 물리적 근접성보다 특정 메트릭에 기반한 상대적 유사성이 더 중요한 시나리오에 적합해요.

방사형 검색을 수행할 때는 k, max_distance, min_score 중에서 쿼리 변수 하나만 지정하면 돼요.

공간

지원되는 공간에 대해서는 공간 문서를 참고하세요.

예제

다음 예제를 참고하면 방사형 검색을 시작하는 데 도움이 될 거예요.

사전 준비 사항

방사형 검색에서 벡터 인덱스를 사용하려면 index.knn을 true로 설정해서 벡터 인덱스를 생성해요. 다음 예제와 같이 knn_vector 데이터 타입의 필드를 하나 이상 지정해요:

PUT knn-index-test
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1,
    "index.knn": true
  },
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "knn_vector",
        "dimension": 2,
        "space_type": "l2",
        "method": {
            "name": "hnsw",
            "engine": "faiss",
            "parameters": {
              "ef_construction": 100,
              "m": 16,
              "ef_search": 100
            }
          }
      }
    }
  }
}

{% include copy-curl.html %}

인덱스를 생성한 다음에는 다음과 유사한 데이터를 추가해요:

PUT _bulk?refresh=true
{"index": {"_index": "knn-index-test", "_id": "1"}}
{"my_vector": [7.0, 8.2], "price": 4.4}
{"index": {"_index": "knn-index-test", "_id": "2"}}
{"my_vector": [7.1, 7.4], "price": 14.2}
{"index": {"_index": "knn-index-test", "_id": "3"}}
{"my_vector": [7.3, 8.3], "price": 19.1}
{"index": {"_index": "knn-index-test", "_id": "4"}}
{"my_vector": [6.5, 8.8], "price": 1.2}
{"index": {"_index": "knn-index-test", "_id": "5"}}
{"my_vector": [5.7, 7.9], "price": 16.5}

{% include copy-curl.html %}

예제: max_distance를 사용한 방사형 검색

다음 예제는 max_distance를 사용해 수행한 방사형 검색이에요:

GET knn-index-test/_search
{
    "query": {
        "knn": {
            "my_vector": {
                "vector": [
                    7.1,
                    8.3
                ],
                "max_distance": 2
            }
        }
    }
}

{% include copy-curl.html %}

제곱 유클리드 거리(l2^2)가 2 이내에 해당하는 모든 문서가 다음 응답과 같이 반환돼요:

결과 {: .text-delta}
{
    "took": 6,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 4,
            "relation": "eq"
        },
        "max_score": 0.98039204,
        "hits": [
            {
                "_index": "knn-index-test",
                "_id": "1",
                "_score": 0.98039204,
                "_source": {
                    "my_vector": [
                        7.0,
                        8.2
                    ],
                    "price": 4.4
                }
            },
            {
                "_index": "knn-index-test",
                "_id": "3",
                "_score": 0.9615384,
                "_source": {
                    "my_vector": [
                        7.3,
                        8.3
                    ],
                    "price": 19.1
                }
            },
            {
                "_index": "knn-index-test",
                "_id": "4",
                "_score": 0.62111807,
                "_source": {
                    "my_vector": [
                        6.5,
                        8.8
                    ],
                    "price": 1.2
                }
            },
            {
                "_index": "knn-index-test",
                "_id": "2",
                "_score": 0.5524861,
                "_source": {
                    "my_vector": [
                        7.1,
                        7.4
                    ],
                    "price": 14.2
                }
            }
        ]
    }
}

예제: max_distance와 필터를 사용한 방사형 검색

다음 예제는 max_distance와 응답 필터를 사용해 수행한 방사형 검색이에요:

GET knn-index-test/_search
{
  "query": {
    "knn": {
      "my_vector": {
        "vector": [7.1, 8.3],
        "max_distance": 2,
        "filter": {
          "range": {
            "price": {
              "gte": 1,
              "lte": 5
            }
          }
        }
      }
    }
  }
}

{% include copy-curl.html %}

제곱 유클리드 거리(l2^2)가 2 이내이면서 가격이 1부터 5 사이에 있는 모든 문서가 다음 응답과 같이 반환돼요:

결과 {: .text-delta}
{
    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 0.98039204,
        "hits": [
            {
                "_index": "knn-index-test",
                "_id": "1",
                "_score": 0.98039204,
                "_source": {
                    "my_vector": [
                        7.0,
                        8.2
                    ],
                    "price": 4.4
                }
            },
            {
                "_index": "knn-index-test",
                "_id": "4",
                "_score": 0.62111807,
                "_source": {
                    "my_vector": [
                        6.5,
                        8.8
                    ],
                    "price": 1.2
                }
            }
        ]
    }
}

예제: min_score를 사용한 방사형 검색

다음 예제는 min_score를 사용해 수행한 방사형 검색이에요:

GET knn-index-test/_search
{
  "query": {
    "knn": {
      "my_vector": {
        "vector": [7.1, 8.3],
        "min_score": 0.95
      }
    }
  }
}

{% include copy-curl.html %}

점수가 0.9 이상인 모든 문서가 다음 응답과 같이 반환돼요:

결과 {: .text-delta}
{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 0.98039204,
        "hits": [
            {
                "_index": "knn-index-test",
                "_id": "1",
                "_score": 0.98039204,
                "_source": {
                    "my_vector": [
                        7.0,
                        8.2
                    ],
                    "price": 4.4
                }
            },
            {
                "_index": "knn-index-test",
                "_id": "3",
                "_score": 0.9615384,
                "_source": {
                    "my_vector": [
                        7.3,
                        8.3
                    ],
                    "price": 19.1
                }
            }
        ]
    }
}

예제: min_score와 필터를 사용한 방사형 검색

다음 예제는 min_score와 응답 필터를 사용해 수행한 방사형 검색이에요:

GET knn-index-test/_search
{
    "query": {
        "knn": {
            "my_vector": {
                "vector": [
                    7.1,
                    8.3
                ],
                "min_score": 0.95,
                "filter": {
                    "range": {
                        "price": {
                            "gte": 1,
                            "lte": 5
                        }
                    }
                }
            }
        }
    }
}

{% include copy-curl.html %}

점수가 0.9 이상이면서 가격이 1부터 5 사이에 있는 모든 문서가 다음 예제와 같이 반환돼요:

결과 {: .text-delta}
{
    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 0.98039204,
        "hits": [
            {
                "_index": "knn-index-test",
                "_id": "1",
                "_score": 0.98039204,
                "_source": {
                    "my_vector": [
                        7.0,
                        8.2
                    ],
                    "price": 4.4
                }
            }
        ]
    }
}

예제: 중첩 필드에 대한 방사형 검색

다음 예제는 중첩 벡터 필드에 방사형 검색을 수행하는 방법을 보여줘요. 먼저 중첩된 knn_vector 필드를 포함하는 인덱스를 생성해요:

PUT nested-knn-index
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1,
    "index.knn": true
  },
  "mappings": {
    "properties": {
      "my_embeddings": {
        "type": "nested",
        "properties": {
          "embedding": {
            "type": "knn_vector",
            "dimension": 3,
            "method": {
              "engine": "faiss",
              "space_type": "innerproduct",
              "name": "hnsw",
              "parameters": {
                "ef_construction": 100,
                "m": 16
              }
            }
          }
        }
      }
    }
  }
}

{% include copy-curl.html %}

인덱스에 샘플 데이터를 추가해요:

PUT _bulk?refresh=true
{"index": {"_index": "nested-knn-index", "_id": "1"}}
{"my_embeddings": [{"embedding": [0.1, 0.2, 0.3]}]}
{"index": {"_index": "nested-knn-index", "_id": "2"}}
{"my_embeddings": [{"embedding": [0.4, 0.5, 0.6]}]}
{"index": {"_index": "nested-knn-index", "_id": "3"}}
{"my_embeddings": [{"embedding": [0.7, 0.8, 0.9]}]}

{% include copy-curl.html %}

my_embeddings.embedding 중첩 필드에 방사형 검색을 수행해서, 쿼리 벡터와 유사하면서 유사도 점수가 0.7 이상인 모든 임베딩을 찾아 보세요:

GET nested-knn-index/_search
{
  "query": {
    "nested": {
      "path": "my_embeddings",
      "query": {
        "knn": {
          "my_embeddings.embedding": {
            "vector": [0.2, 0.3, 0.4],
            "min_score": 0.7
          }
        }
      },
      "score_mode": "max"
    }
  }
}

{% include copy-curl.html %}

이 쿼리는 Lucene 엔진과 Faiss 엔진 모두에서 동작하고, 중첩 벡터 임베딩이 최소 유사도 점수 임계값을 충족하는 문서를 다음 응답과 같이 반환해요:

결과 {: .text-delta}
{
  "took": 43,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 1.74,
    "hits": [
      {
        "_index": "nested-knn-index",
        "_id": "3",
        "_score": 1.74,
        "_source": {
          "my_embeddings": [
            {
              "embedding": [0.7, 0.8, 0.9]
            }
          ]
        }
      },
      {
        "_index": "nested-knn-index",
        "_id": "2",
        "_score": 1.47,
        "_source": {
          "my_embeddings": [
            {
              "embedding": [0.4, 0.5, 0.6]
            }
          ]
        }
      }
    ]
  }
}

더 알아보기 (Learn more)