Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

ICE 내부 특정 NodeType에 대한 쿼리를 실행하기 위한 API 유형으로, 다음과 같은 추가적인 항목을 정의한다.

...

Expand
title"useCacheKey": true
Code Block
{
  "typeId": "api",
  "category": "snack",
  "apiId": "list",
  "apiName": "snack List",
  "apiType": "service",
  "method": "GET",
  "parameters": [
  ],
  "statistic": true,
  "aggregation": false,
  "root": {
    "configId": "root",
    "tid": "snack",
    "type": "query",
    "cacheable": true,
    "cacheTime": 60,
    "customResponse": "sampleResponse",
    "query": [
      {
        "method": "matchingShould",
        "field": "id",
        "value": "{{:id}}"
      },
      {
        "method": "matchingShould",
        "field": "name",
        "value": "{{:name}}"
      }
    ],
    "response": [
      {
        "field": "_all_",
        "type": "all"
      }
    ]
  }

{{protocol}}://{{hostname}}:{{port}}/svc/snack/list?_siteId=bestshop&id=104&name=오레오

cacheKey api::snack>list?&id.matchingShould=104&name.matchingShould=오레오

Code Block
{
    "result": "200",
    "resultMessage": "SUCCESS",
    "totalCount": 2,
    "totalTypeCount": 20,
    "resultCount": 2,
    "items": [
        {
            "id": "104",
            "label": "쿠크다스",
            "name": "쿠크다스",
            "idx": 1
        },
        {
            "id": "103",
            "label": "오레오",
            "name": "오레오",
            "idx": 2
        }
    ]
}

Expand
title"useCacheKey": false
Code Block
{
  "typeId": "api",
  "category": "snack",
  "apiId": "list",
  "apiName": "snack List",
  "apiType": "service",
  "method": "GET",
  "parameters": [
  ],
  "statistic": true,
  "aggregation": false,
  "root": {
    "configId": "root",
    "tid": "snack",
    "type": "query",
    "cacheable": true,
    "cacheTime": 60,
    "customResponse": "sampleResponse",
    "query": [
      {
        "method": "matchingShould",
        "field": "id",
        "value": "{{:id}}",
        "useCacheKey": false
      },
      {
        "method": "matchingShould",
        "field": "name",
        "value": "{{:name}}"
      }
    ],
    "response": [
      {
        "field": "_all_",
        "type": "all"
      }
    ]
  }
}

{{protocol}}://{{hostname}}:{{port}}/svc/snack/list?_siteId=bestshop&id=104&name=오레오{{protocol}}://{{hostname}}:{{port}}/svc/snack/list?_siteId=bestshop&id=105&name=오레오

cacheKey api::snack>list?&name.matchingShould=오레오

cacheKey에서 id 제외

[ id=104, name=오레오 ] 로 검색 후 cacheKey에 60초간 캐싱

이후 [ id=105, name=오레오 ] 로 검색하더라도 60초간 응답결과는 변화가 없다.

Code Block
{
    "result": "200",
    "resultMessage": "SUCCESS",
    "totalCount": 2,
    "totalTypeCount": 20,
    "resultCount": 2,
    "items": [
        {
            "id": "104",
            "label": "쿠크다스",
            "name": "쿠크다스",
            "idx": 1
        },
        {
            "id": "103",
            "label": "오레오",
            "name": "오레오",
            "idx": 2
        }
    ]
}

...

커스텀 처리가 필요한 경우 해당 서비스 정의를 해야한다.

아래는 상품 통합 검색 API에 customFilter를 추가하는 사례이다.

  • Class 추가

    • location : net/ion/ice/core/query/filter

    • implements QueryFilter 하는 class 를 하나 생성한다.

  • @Component 어노테이션 추가

    • @Component("productSearchFilter")

  • custom 질의 작성

    • createQuery안에 Lucene에서 제공하는 쿼리로 직접 질의를 작성할 수 있다.

Code Block
@Override
@Component("sampleFilter")
public Queryclass createQuery(QueryContext context) SampleFilter implements QueryFilter{
    @Override
   BooleanQuery.Builder searchQueryBuilderpublic =Query new BooleanQuery.Builder();
createQuery(QueryContext context) {
        StringBooleanQuery.Builder searchValuesearchQueryBuilder = new contextBooleanQuery.getDataStringValueBuilder("searchValue");
        String reSearchValuetags = context.getDataStringValue("reSearchValuetags"); //결과 내 재검색

        if ("".equals(searchValuetags)) {
            return null;
        }
         if (!"".equals(searchValue)) {BooleanQuery.Builder searchValueQueryBuilder = new BooleanQuery.Builder();
        try {
   BooleanQuery.Builder searchValueQueryBuilder = getSearchValueBuilder(searchValue);      Query tagsQuery =     searchQueryBuilder.add(searchValueQueryBuilder.build(), BooleanClause.Occur.MUST);
        }LuceneQueryUtils.createLuceneQuery(new QueryTerm(QueryTerm.QueryTermType.NODE, "tags", "code", "matching", tags, PropertyType.ValueType.STRING));
           return searchQueryBuildersearchValueQueryBuilder.build(add(tagsQuery, BooleanClause.Occur.SHOULD);
}
  • apiConfig에 customFilter 세팅

    • @Component 어노테이션 명으로 작성한다.

Code Block
{   "configId": "root",   "tid": "siteProduct",
  "type": "query",
  "customFilter": "productSearchFilter",
}

Sample

Code Block
languagejson
{
    "typeId": "api", } catch (IOException e) {
        }
       "category": "product", searchQueryBuilder.add(searchValueQueryBuilder.build(), BooleanClause.Occur.MUST);
    "apiId": "search",   return  "apiName": "Product Search List",
    "apiType": "service",searchQueryBuilder.build();
    }
}

  • apiConfig에 customFilter 세팅

    • @Component 어노테이션 명으로 작성한다.

  • 아래 API 설명

    • apiConfig query

      • name을 wildcard로 쿼리

    • customFilter

      • tags를 matching으로 쿼리

name의 "analyzer": "simple" - like 검색을 wildcard로 할 수 있다.

tags의 "analyzer": "code" - 콤마로 tokenize 되어있으므로 쪼개진 word에 대하여 matching으로 equals 검색을 할 수 있다.

Expand
titlesample snack schema 정의 참조
Code Block
[
  {
    "
method
typeId": "
GET
nodeType",
    "
parameters
tid": 
[
"snack",
    
{
"parentId": "test",
    
"
parameter
repositoryType": "
categoryId
node",

    "
name
typeName": "
카테고리아이디
간식",
    "standaloneIndex": false,
    "
valueType
microservice": "
STRING
test",
    
"
required
propertyTypes": 
false },
[
      {
        "
parameter
pid": "
searchValue
id",
        "name": "
검색어
ID",
        "valueType": "STRING",
        "
required
idable": 
false
true,
      
}
  
]
"indexable": true,
    
"statistic":
 
true,
   "
aggregation
labelable": false,
    
"root": {
    "
configId
required": 
"root"
true,
        "
tid
idType": "
siteProduct
",
        "
type
orderNo": 
"query",
10
      
"allowParams": false,
},
      {
"orderNo":
 
1,
       "
cacheable
pid": 
true
"name",
        "
cacheTime
name": 
60
"Name",
        "
customResponse
valueType": "
productListResponse
STRING",
        "
customFilter
indexable": 
"productSearchFilter"
true,
        "
query
analyzer": 
[
"simple",
        
{
"labelable": true,
        "
method
required": 
"matching"
true,

        "
field
orderNo":
"site",
 20
      },
     
"value":
 
"{{:_siteId}}"
{
        
}
"pid": "vendor",
        
{
"name": "vendor",
        "
method
valueType": "
matching
STRING",

        "
field
indexable": 
"approvalStatus"
true,

        "
value
analyzer": "
approval"
code ",
        "orderNo": 30
  
},
    },
    
{
  {
        "
method
pid": "
matching
tags",
        
"name"
field"
: "
saleStatus
tags",

        
"
value
valueType": "
selling
STRING",
        
}
"indexable": true,
        
{
"analyzer": "code",
        "
method
orderNo": 
"matching",
40
      }
   
"field": "exposure",
 ]
  }
]

Code Block
{
    "valuetypeId": "trueapi",
        }"category": "snack",
    "apiId": "search",
  {  "apiName": "snack search  List",
    "methodapiType": "matchingservice",
    "method": "GET",
    "fieldparameters": "deleted", [
      {
        "valueparameter": "falsename",
         }"name": "이름",
        {
          "method"valueType": "sortingSTRING",
          "valuerequired": "{{:sorting}},id desc"false
        },
 
      {
 
        "methodparameter": "pagetags",
 
        "valuename": "{{:page}}"검색어",
         }"valueType": "STRING",
        {"required": false
      }
   "method": "pageSize" ],
    "statistic": true,
    "valueaggregation": "{{:pageSize}}"false,
    "root": {
  },    "configId": "root",
   {   "tid": "snack",
      "methodtype": "matchingquery",
      "customFilter": "sampleFilter",
      "query": [
        {
          "method": "wildcard",
          "field": "siteCategoriesname",
          "value": "{{:categoryIdname}}"
        }
      ],
      "response": [
        {
          "field": "id",
          "type": "field",
          "value": ""
        },
        {
          "field": "name",
          "type": "field",
          "value": ""
        },
        {
          "field": "siteCategoriesvendor",
          "type": "field",
          "value": ""
        },
        {
          "field": "siteProductSaleInfotags",
          "type": "field",
          "value": ""
        },
      ]
 {   }
  }
  • name like ‘%오레오%’인 검색 결과

Code Block
{{protocol}}://{{hostname}}:{{port}}/svc/snack/search?_siteId=bestshop&name=오레오

{
  "field": "images",
          "type": "field",
          "value": "baseProduct.images"
        },
        {
          "field": "created",
          "type": "field",
          "value": "baseProduct.created"
        }
      ]
    }
     "result": "200",
    "resultMessage": "SUCCESS",
    "totalCount": 3,
    "totalTypeCount": 20,
    "resultCount": 3,
    "items": [
        {
            "id": "103",
            "name": "오레오",
            "vendor": "크래프트푸즈,동서식품",
            "tags": "초콜릿쿠키,하얀크림,샌드"
        },
        {
            "id": "119",
            "name": "오레오 민트초코",
            "vendor": "크래프트푸즈,동서식품",
            "tags": "민트초코,초코쿠키"
        },
        {
            "id": "120",
            "name": "오레오 딸기",
            "vendor": "크래프트푸즈,동서식품",
            "tags": "딸기"
        }
    ]
}
  • name like ‘%오레오%’ 이고 tags include ‘민트초코’ 인 검색 결과

Code Block
{{protocol}}://{{hostname}}:{{port}}/svc/snack/search?_siteId=bestshop&name=오레오&tags=민트초코

{
    "result": "200",
    "resultMessage": "SUCCESS",
    "totalCount": 1,
    "totalTypeCount": 20,
    "resultCount": 1,
    "items": [
        {
            "id": "119",
            "name": "오레오 민트초코",
            "vendor": "크래프트푸즈,동서식품",
            "tags": "민트초코,초코쿠키"
        }
    ]
}