검색 권장사항

이 문서에서는 Search API를 위한 권장사항을 제공합니다. 또한 문서 전체에서 쿼리 문자열을 구분할 때 작은따옴표(‘’)를 사용합니다. 이렇게 함으로써 다음과 같이 큰따옴표로 묶인 여러 개의 어구가 포함된 쿼리를 혼동 없이 구분할 수 있습니다. ‘field:"some text" some-value’.

Index.put() 및 Index.delete() 호출의 일괄 처리

색인에 문서를 추가하거나 삭제할 때 한 번에 최대 200개의 문서를 전달할 수 있습니다. 이렇게 하면 한 번에 하나씩 처리하는 것보다 훨씬 더 효율적입니다.

문서 순위를 사용하여 문서를 사전에 정렬하기

기본적으로, 검색 결과는 내림차순으로 반환됩니다. 그리고 Search API는 기본적으로 모든 문서의 순위를 2011년 1월 1일 이후로 경과된 초 수로 설정합니다. 따라서 처음에는 가장 최신 상태의 문서가 반환됩니다. 그러나 문서를 추가된 시간을 기준으로 정렬할 필요가 없다면 순위를 다른 목적으로 사용해도 됩니다. 부동산 애플리케이션이 있다고 가정해 보겠습니다. 고객이 가장 원하는 것은 가격을 기준으로 한 분류입니다. 기본 정렬의 효율을 개선하려면 주택 가격에 따라 순위를 설정할 수 있을 것입니다.

낮은 가격에서 높은 가격 또는 높은 가격에서 낮은 가격 등 여러 가지 정렬 순서가 필요한 경우 각 순서마다 별도의 색인을 만들 수 있습니다. 어떤 색인은 순위 = 가격과 또 다른 순위 = MAXINT-가격(순위는 양수여야 하므로)을 가질 것입니다.

순위를 정렬 키로 사용하면 검색 성능이 개선됩니다. 다른 정렬 키를 지정하려면 검색 결과의 수를 문서 10,000개로 제한하는 정렬 옵션을 사용해야 합니다. 이 경우 순위에 의해 결정된 정렬 순서가 어떤 문서가 정렬에 포함될지를 결정합니다. 자세한 내용은 정렬 옵션을 읽어보세요.

부울 데이터에 atom 필드 사용하기

부울 데이터를 숫자 필드에 저장하는 것은 매우 비효율적입니다. 대신 Atom 필드를 사용하고 선호하는 상수(True/False, yes/no, 0/1)를 할당하세요.

부정 검색을 긍정 검색으로 바꾸기

어떤 요리를 제공하는지 알 수 없는 레스토랑을 식별하기 위한 특수 용어가 있다고 가정해 보겠습니다. 이러한 레스토랑을 제외하려면 ‘NOT cuisine:undefined’를 쿼리로 사용할 수 있습니다. 하지만 이 방법은 그 반대의 경우, 즉 어떤 요리를 제공하는지 아는 레스토랑을 찾는 것보다 청구 가능 작업과 계산 시간이라는 모든 면에서 평가 비용이 더 비쌉니다. 이 경우 cuisine이라는 필드 하나만 사용하는 대신 cuisinecuisine_known(Atom 필드)이라는 2개의 필드를 사용할 수 있습니다. 어떤 요리를 제공하는지 아는 레스토랑의 경우 첫 번째 필드를 실제 요리로 설정하고 두 번째 필드를 "yes"로 설정합니다. 어떤 요리를 제공하는지 알 수 없는 레스토랑의 경우에는 요리를 ""(빈 문자열)로 설정하고 cuisine_known"no"로 설정합니다. 이제 어떤 요리를 제공하는지 알려진 식당을 찾으려면 부정보다 훨씬 더 빠른 ‘cuisine_known:yes’ 쿼리를 실행할 수 있습니다.

논리합을 논리곱으로 바꾸기

'OR' 논리합은 비용이 청구가 되는 작업과 계산 시간의 모든 측면에서 비용이 많이 드는 연산입니다 ‘cuisine:Japanese OR cuisine:Korean’을 검색하려고 한다고 가정해 보겠습니다. 한 가지 대안은 문서에 더 일반적인 범주의 요리를 색인으로 설정하는 것입니다. 이 경우 쿼리는 ‘cuisine:Asian’으로 더 간단해질 것입니다.

쿼리에서 항진명제를 제거하기

토론토에 있는 모든 식당을 찾으려고 한다고 가정해 보겠습니다. 문서에 'city'라는 이름의 필드 하나만 있다고 가정할 때 쿼리 ‘city:toronto AND NOT city:montreal’을 사용할 경우 도시가 ‘city:toronto’로 설정되면 "toronto"로 설정될 수 없기 때문에 "montreal"와 동일한 결과를 얻게 됩니다. 두 번째 쿼리는 단어가 하나뿐이므로 훨씬 더 빨리 실행됩니다. 첫 번째 쿼리는 3가지 단계를 수행합니다. 첫째, 도시가 'toronto'로 설정된 문서 목록을 찾고, 그 다음에 도시가 'montreal'로 설정되지 않은 모든 도시의 목록을 찾고, 마지막으로 두 목록의 중첩되는 부분을 계산합니다.

정렬하기 전에 범위 좁히기

애플리케이션이 전 세계의 식당에 관한 정보를 저장하고 있고 현재 사용자에게 가장 가까이 있는 식당을 보여주려고 한다고 가정해 보겠습니다. 한 가지 방법은 일치하는 여러 문서를 사용자 위치와의 거리를 기준으로 정렬하는 것입니다. 그러나 식당이 1,000,000개가 있다면 ‘cuisine:japanese’와 같은 쿼리를 distance(geopoint(x, y), restaurant_loc) 정렬 표현식과 함께 실행할 경우 시간이 오래 걸립니다. 쿼리에 여러 가지 필터를 추가하여 좀더 핵심적인 문서 집합에서부터 정렬을 시작하는 것이 좋습니다. 한 가지 해법은 국가, 주, 도시와 같은 지리적 범주를 만들어서 사용자의 위치를 통해 도시와 주를 추론할 수 있게 하는 것입니다. 그러면 쿼리가 ‘cuisine:japanese AND city:<user-city>’와 같이 됩니다. 더 이상 1,000,000개의 문서를 정렬할 필요가 없어질 가능성이 큽니다.

좁은 범주를 사용하여 정렬을 피하거나 최소화하기

순위를 사용하여 레스토랑을 가격별로 정렬할 경우 가격 카테고리(price_0_10, price_11_20, price_21_30, price_31_40, price_41_lots)를 포함하는 price_range 필드를 만들 수 있습니다. 그러면 ‘price_range:price_21_30 OR price_range:price_31_40’ 쿼리를 사용하여 전혀 정렬 작업을 수행하지 않고도 가격이 $21~$40인 모든 레스토랑을 찾을 수 있습니다. 적용되는 범주가 깔끔하게 정해지지 않는 경우가 많지만 이 기법을 사용하면 ‘... AND price>25 AND price<35’와 같은 고비용의 쿼리로 검색 범위를 좁히기 전에 많은 양의 문서를 거부할 수 있습니다.

필요하지 않은 경우 일치 결과에 점수 매기지 않기

점수는 지정된 문서가 쿼리에 얼마나 잘 일치하는지를 나타내는 데 사용됩니다. 하지만 점수를 기준으로 정렬하지 않을 것이라면 점수를 요청하지 마세요. 검색 처리 속도만 늦출 뿐입니다.