상품 속성별 검색을 사용하면 문서에 카테고리 정보를 연결할 수 있습니다. 상품 속성은 속성/값 쌍입니다. 예를 들어 이름이 'size'인 상품 속성의 값은 'small', 'medium', 'large'입니다.
검색에 상품 속성을 사용하면 쿼리를 세분화하고 여러 단계에 걸친 결과를 '자세히 살펴보는' 데 도움이 되는 요약 정보를 검색할 수 있습니다.
이 기능은 고객이 제품 검색 범위를 좁혀 원하는 제품을 볼 수 있도록 필터 세트를 제공해야 하는 쇼핑 사이트와 같은 애플리케이션에 유용합니다.
상품 속성에 대해 집계된 데이터는 상품 속성 값이 분포된 방식을 보여줍니다. 예를 들어 'size' 상품 속성은 결과 집합에서 여러 문서에 표시될 수 있습니다. 이 상품 속성에 대해 집계된 데이터에는 'small' 값이 100회, 'medium' 값이 300회, 'large' 값이 250회 표시될 수 있습니다. 각 상품 속성/값 쌍은 쿼리 결과에 포함된 문서의 하위 집합을 나타냅니다. 상세검색이라 하는 키가 각 쌍과 연결됩니다. 쿼리에 상세검색을 포함하면 쿼리 문자열과 일치하고 하나 이상의 상세검색에 따라 상품 속성 값을 포함하는 문서를 검색할 수 있습니다.
검색 수행 시 수집하고 결과와 함께 표시할 상품 속성을 선택하거나, 문서에서 가장 많이 표시된 상품 속성을 자동으로 선택하도록 상품 속성 검색을 사용 설정할 수 있습니다.
문서에 상품 속성 추가
문서에 상품 속성을 추가한 후 색인에 문서를 추가합니다. 문서 필드를 지정하면서 동시에 이 작업을 수행합니다.
package com.google.test.facet;
import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.search.*;
public class FacetsearchjavaServlet extends HttpServlet {
public void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Document doc1 = Document.newBuilder()
.setId("doc1")
.addField(Field.newBuilder().setName("name").setAtom("x86"))
.addFacet(Facet.withAtom("type", "computer"))
.addFacet(Facet.withNumber("ram_size_gb", 8.0))
.build();
IndexSpec indexSpec = IndexSpec.newBuilder().setName("products").build();
Index index = SearchServiceFactory.getSearchService().getIndex(indexSpec);
index.put(doc1);
}
}
상품 속성은 문서 필드와 비슷합니다. 상품 속성에는 이름이 있고 값 한 개를 사용합니다.
상품 속성 이름은 문서 필드와 동일한 규칙을 따릅니다. 이름은 대소문자를 구분하며 ASCII 문자만 포함할 수 있습니다. 문자로 시작해야 하며 문자, 숫자, 밑줄로 구성될 수 있습니다. 필드 이름은 영문 500자를 초과할 수 없습니다.
상품 속성의 값은 원자 문자열(영문 500자 이하) 또는 숫자(-2,147,483,647에서 2,147,483,647 사이의 배정밀도 부동 소수점 값)일 수 있습니다.
이름과 유형이 같은 상품 속성을 추가하고 매번 다른 값을 사용하여 한 문서에서 한 상품 속성에 여러 값을 할당할 수 있습니다.
상품 속성에 포함할 수 있는 값의 수에는 제한이 없습니다. 또한 문서에 추가할 수 있는 상품 속성 수 또는 색인에 있는 고유한 이름의 상품 속성 수에도 제한이 없습니다.
상품 속성을 사용할 때마다 원자 또는 숫자 값을 가질 수 있습니다. 이름이 'size'인 상품 속성을 문자열 값 'small'이 포함된 한 문서와 숫자 값 8이 포함된 다른 문서에 연결할 수 있습니다. 실제로 동일한 상품 속성이 두 종류의 값을 모두 포함한 채로 같은 문서에 여러 번 나타날 수 있습니다. 허용된다고 할지라도 동일 상품 속성에 원자 값과 숫자 값을 모두 사용하는 것은 피하는 것이 좋습니다.
상품 속성을 문서에 추가할 때 특정 유형이 포함된 경우, 검색 결과는 해당하는 모든 값을 수집합니다. 예를 들어, 상품 속성 'size'에 대한 결과에 'small' 값 인스턴스 100개, 'medium' 값 인스턴스 150개, [4, 8) 범위의 숫자 값 인스턴스 135개가 표시될 수 있습니다. 정확한 숫자 값과 해당 빈도 분포는 표시되지 않습니다.
쿼리를 사용해서 문서를 검색할 때는 해당 상품 속성 및 값에 직접 액세스할 수 없습니다. 다음 섹션에 설명된 대로 쿼리를 사용해서 상품 속성 정보가 반환되도록 요청해야 합니다.
상품 속성별 검색을 사용하여 상품 속성 정보 검색
검색 백엔드에 가장 자주 사용된 상품 속성을 검색하도록 요청할 수 있습니다. 이를 자동 상품 속성 검색이라고 부릅니다. 또한 이름이나 이름 및 값을 기준으로 상품 속성을 선택하여 상품 속성 정보를 명시적으로 검색할 수도 있습니다. 이 세 가지 종류의 상품 속성 검색을 하나의 단일 쿼리에서 모두 혼합하여 사용할 수 있습니다.
상품 속성 정보 요청은 쿼리가 반환하는 문서에는 영향을 주지 않지만, 성능에는 영향을 미칠 수 있습니다. 기본 깊이 1000으로 상품 속성별 검색을 수행하는 것은 정렬 옵션 점수 한도를 1000으로 설정하는 것과 동일한 효과가 있습니다.
자동 상품 속성 검색
자동 상품 속성 검색은 사용자 문서의 집계에 가장 자주 표시되는 상품 속성을 찾습니다. 예를 들어 쿼리와 일치하는 문서에 'red' 값이 5회, 'white' 값이 5회, 'blue' 값이 5회로 표시된 'color' 상품 속성이 있다고 가정해 보겠습니다. 이 상품 속성에는 총 15개의 값이 있습니다. 검색 목적에 따라 동일한 일치 문서에서 'dark' 값이 6회, 'light' 값이 7회로 표시된 또 다른 상품 속성인 'shade'보다는 이 속성이 순위가 높게 표시될 것입니다.
쿼리에서 다음과 같이 설정하여 상품 속성 검색을 사용 설정해야 합니다.
package com.google.test.facet;
import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.search.*;
public class FacetsearchjavaServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
IndexSpec indexSpec = IndexSpec.newBuilder().setName("products").build();
Index index = SearchServiceFactory.getSearchService().getIndex(indexSpec);
Results<ScoredDocument> result = index.search(
Query.newBuilder().setEnableFacetDiscovery(true) // enable discovery
.build("name:x86"));
for(FacetResult facetResult : result.getFacets()) {
resp.getWriter().printf("Facet %s:\n", facetResult.getName());
for (FacetResultValue facetValue : facetResult.getValues()) {
resp.getWriter().printf(" %s: Count=%s, RefinementKey=%s\n",
facetValue.getLabel(),
facetValue.getCount(),
facetValue.getRefinementToken());
}
}
}
}
상품 속성을 검색하면 기본적으로 해당 상품 속성에서 가장 자주 발견되는 값 10개만 반환됩니다.
FacetOptions.Builder.setDiscoveryValueLimit()
를 사용하여 이 한도를 최대 100까지 늘릴 수 있습니다.
자동 상품 속성 검색에서는 가능한 모든 상품 속성과 해당 값을 반환하지 않습니다. 검색에서 반환되는 상품 속성은 실행 조건에 따라 다를 수 있습니다. 고정된 상품 속성 집합이 필요한 경우에는 쿼리에 return_facets
매개변수를 사용하세요.
문자열 값은 개별적으로 반환됩니다. 검색된 상품 속성의 숫자 값은 단일 범위 [최소 최대)로 반환됩니다. 이 범위를 조사하고 이후 쿼리를 위해 더 작은 하위 범위를 만들 수 있습니다.
이름별 상품 속성 선택
이름만 사용하여 상품 속성 정보를 검색하려면ReturnFacet
객체를 쿼리에 추가하여 상품 속성 이름을 지정합니다.
package com.google.test.facet;
import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.search.*;
public class FacetsearchjavaServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
IndexSpec indexSpec = IndexSpec.newBuilder().setName("products").build();
Index index = SearchServiceFactory.getSearchService().getIndex(indexSpec);
Results<ScoredDocument> result = index.search(Query.newBuilder()
.addReturnFacet("type")
.addReturnFacet("ram_size_gb")
.build("name:x86"));
for(FacetResult facetResult : result.getFacets()) {
resp.getWriter().printf("Facet %s:\n", facetResult.getName());
for (FacetResultValue facetValue : facetResult.getValues()) {
resp.getWriter().printf(" %s: Count=%s, RefinementKey=%s\n",
facetValue.getLabel(),
facetValue.getCount(),
facetValue.getRefinementToken());
}
}
}
}
이름을 기준으로 상품 속성을 검색하면 기본적으로 해당 상품 속성에서 가장 자주 발견되는 값 10개만 반환됩니다.
FacetOptions.Builder.setDiscoveryValueLimit()
를 사용하여 이 한도를 최대 20까지 늘릴 수 있습니다.
이름 및 값으로 상품 속성 선택
특정 값을 가진 상품 속성을 검색하려면FacetRequest
가 포함된 ReturnFacet
객체를 추가합니다.
package com.google.test.facet;
import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.search.*;
public class FacetsearchjavaServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
IndexSpec indexSpec = IndexSpec.newBuilder().setName("products").build();
Index index = SearchServiceFactory.getSearchService().getIndex(indexSpec);
// Fetch the "type" facet with values "computer and "printer"
// along with the "ram_size_gb" facet with values in the ranges [0,4), [4, 8), and [8, max]
Results<ScoredDocument> result = index.search(Query.newBuilder()
.addReturnFacet(FacetRequest.newBuilder()
.setName("type")
.addValueConstraint("computer")
.addValueConstraint("printer"))
.addReturnFacet(FacetRequest.newBuilder()
.setName("ram_size_gb")
.addRange(FacetRange.withEnd(4.0))
.addRange(FacetRange.withStartEnd(4.0, 8.0))
.addRange(FacetRange.withStart(8.0)))
.build("name:x86"));
for(FacetResult facetResult : result.getFacets()) {
resp.getWriter().printf("Facet %s:\n", facetResult.getName());
for (FacetResultValue facetValue : facetResult.getValues()) {
resp.getWriter().printf(" %s: Count=%s, RefinementKey=%s\n",
facetValue.getLabel(),
facetValue.getCount(),
facetValue.getRefinementToken());
}
}
}
}
단일 FacetRequest
의 값은 모두 같은 유형으로, 문자열 값 목록 또는 숫자의 경우 왼쪽(시작)으로는 닫히고 오른쪽(끝)으로는 열려 있는 구간인 FacetRanges
목록이어야 합니다. 상품 속성에 문자열과 숫자 값이 섞여 있으면 각각에 대해 별도의 FacetRequest를 추가하세요.
옵션
쿼리 호출에FacetOptions
매개변수를 추가하여 상품 속성별 검색을 제어할 수 있습니다.
이 매개변수는 FacetOptions
의 단일 인스턴스를 사용합니다. 이 매개변수를 사용하여 상품 속성별 검색의 기본 동작을 재정의할 수 있습니다.
Results<ScoredDocument> results = index.search(Query.newBuilder()
.addReturnFacet(FacetRequest.newBuilder()
.setName("type")
.addValueConstraint("computer")
.addValueConstraint("printer"))
.addReturnFacet(FacetRequest.newBuilder()
.setName("ram_size_gb")
.addRange(FacetRange.withEnd(4.0))
.addRange(FacetRange.withStartEnd(4.0, 8.0))
.addRange(FacetRange.withStart(8.0)))
.setFacetOptions(FacetOptions.newBuilder()
.setDiscoveryLimit(5)
.setDiscoveryValueLimit(10)
.setDepth(6000).build());
.build("some_query");
매개변수 | 설명 | 기본값 |
---|---|---|
DiscoveryLimit |
상품 속성 검색이 켜져 있는 경우 검색할 상품 속성 수입니다. 0이면 상품 속성 검색이 중지됩니다. | 10 |
DiscoveryValueLimit |
가장 많이 발견된 상품 속성 각각에 대해 반환될 값의 수입니다. | 10 |
Depth |
상품 속성 정보를 수집하기 위해 평가할 쿼리 결과의 최소 문서 수입니다. | 1000 |
Depth
옵션은 이름, 이름과 값, 자동 검색 등 세 가지 종류의 상품 속성 집계에 모두 적용됩니다.
다른 옵션은 자동 검색에만 사용됩니다.
상품 속성 깊이는 일반적으로 쿼리 제한보다 훨씬 큽니다. 상품 속성 결과는 적어도 문서 깊이만큼 계산됩니다. 정렬 옵션 점수 제한을 깊이보다 높게 설정하면 점수 제한이 대신 사용됩니다.
상품 속성 결과 검색
쿼리에서 상품 속성별 검색 매개변수를 사용하면 집계된 상품 속성 정보가 쿼리 결과와 함께 제공됩니다.
쿼리에는 FacetResult
목록이 포함됩니다.
쿼리와 일치하는 문서에 나타나는 각 상품 속성에 대한 하나의 결과가 목록에 포함됩니다. 각 결과에서는 다음을 얻을 수 있습니다.
- 상품 속성 이름
- 상품 속성에 가장 자주 발견되는 값 목록. 각 값별로 대략적인 출현 횟수와 이 쿼리 및 상품 속성 값과 일치하는 문서를 검색하는 데 사용될 수 있는 상세검색 키가 표시됩니다.
값 목록에는 상품 속성의 문자열 및 숫자 값이 포함됩니다. 상품 속성이 자동 검색된 경우, 해당 숫자 값은 단일 구간 [최소 최대)로 반환됩니다. 쿼리에서 범위를 한 개 이상 사용하여 숫자 상품 속성을 명시적으로 요청한 경우, 목록에는 각 범위에 대한 닫힘-열림 구간 [시작 끝) 한 개가 포함됩니다.
쿼리 옵션에 따라 조사할 문서 수와 반환할 값 수가 결정되므로, 상품 속성 값 목록에는 문서에서 발견된 모든 값이 포함되지 않을 수 있습니다.
각 상품 속성에 대해 집계된 정보는 검색 결과에서 확인할 수 있습니다.
Results<ScoredDocument> results = index.search(...);
for (FacetResult facetInfo : results.getFacets()) {
...
}
예를 들어, 쿼리를 통해 문자열 값과 숫자 값이 있는 'size' 상품 속성을 포함하는 문서가 발견되었을 수 있습니다. 이 상품 속성의 FacetResult는 다음과 같이 구성됩니다.
FacetResult.newBuilder()
.setName("size")
.addValue(FacetResultValue.create("[8, 10)", 22, refinement_key)
.addValue(FacetResultValue.create("small", 100, refinement_key)
.addValue(FacetResultValue.create("medium", 300, refinement_key)
.addValue(FacetResultValue.create("large", 250, refinement_key).build());
FacetResultValue.label은 상품 속성 값에서 구성됩니다. 숫자 값은 '문자열화된' 범위 표현으로 반환됩니다.
refinement_key
는 이후 쿼리에서 결과의 상품 속성 이름 및 값과 일치하는 문서를 검색하는 데 사용할 수 있는 웹/URL 안전 문자열입니다.
상품 속성을 사용하여 쿼리 세분화/필터링
Query query = Query.newBuilder()
.addFacetRefinementFromToken(refinement_key1)
.addFacetRefinementFromToken(refinement_key2)
.addFacetRefinementFromToken(refinement_key3)
.build("some_query");
동일 요청에서 1개 이상의 서로 다른 상품 속성에 대한 상세검색을 조합할 수 있습니다. 동일 상품 속성에 속하는 모든 상세검색은 OR로 연결하고, 서로 다른 상품 속성에 대한 상세검색은 AND로 결합합니다.
또한 커스텀 FacetRefinement
키를 직접 만들 수 있습니다. 자세한 내용은 클래스 문서를 참조하세요.