AWS CloudSearch


AWS 관련자료가 원래 잘 없지만 CloudSearch 에 대한 자료는 더 없고

Java SDK 를 사용한 자료는 더 없다. 


간단하게 검색하는 방법입니다.


Document 를 업데이트하는건 전편에 설명



Java


AmazonCloudSearchDomainClient domain = new AmazonCloudSearchDomainClient(getCredentials());
domain.setEndpoint("search-**************.cloudsearch.amazonaws.com");

SearchRequest request = new SearchRequest();

long pageSize = 20;
long startIndex = 0 * pageSize; // 기본 0

String sort = "_score desc,id desc";

String filterQuery = "kind:'hello'";
String returnFields = "_all_fields,_score";
String queryOptions = "{ \n" +
" \"defaultOperator\":\"or\",\n" +
" \"fields\":[ \n" +
" \"name^5\",\n" +
" \"description^3\",\n" +
" \"tags^3\",\n" +
" \"colors^3\",\n" +
" \"category_names^3\",\n" +
" \"file_extensions^2\",\n" +
" \"creator_name\"\n" +
" ],\n" +
" \"operators\":[ \n" +
" \"and\",\n" +
" \"escape\",\n" +
" \"fuzzy\",\n" +
" \"near\",\n" +
" \"not\",\n" +
" \"or\",\n" +
" \"phrase\",\n" +
" \"precedence\",\n" +
" \"prefix\",\n" +
" \"whitespace\"\n" +
" ]\n" +
"}";

request.withQueryParser(QueryParser.Simple)
.withQuery(keyword)
.withStart(startIndex)
.withSize(pageSize)
.withSort(sort)
.withFilterQuery(filterQuery)
.withReturn(returnFields)
.withQueryOptions(queryOptions)
;

SearchResult searchResult = domain.search(request);

queryOptions 의 fields 는 검색대상들이며

name^5 라고 된것이 있는데

field에 weight 를 주고 _score 를 높여 더 높은 검색순위로 끌어올릴 수 있다.

기본 weight는 1 이고, 0.1 도 가능



Query 표현식 조합 방법은

http://docs.aws.amazon.com/cloudsearch/latest/developerguide/searching-compound-queries.html



예를 들어 filterQuery 를 조합할때


kind:hello 이고, status:Active, 이고, category_codes Array 값중 30이 포함된 항목을 필터링 하고싶으면


(and kind:'hello' status:'Active' (phrase field='category_codes' 30) )






Result

{
"status": {
"timems": 5,
"rid": "/M7W4bsqOgq1pko\u003d"
},
"hits": {
"found": 8,
"start": 0,
"hit": [
{
"id": "Marketplace_291",
"fields": {
"thumbnail": [
"http://**************/7b12910b-cc3c-4494-a504-ba00226b27f7.jpg"
],
"kind": [
"Marketplace"
],
"description": [
"Test"
],
"category_names": [
"Video Motion",
"Apple Motion Templates",
"Product Promo"
],
"_score": [
"15.213767"
],
"file_size": [
"21798.0"
],
"file_extensions": [
"jpg"
],
"happened_date": [
"2016-03-28T07:16:41.984Z"
],
"category_codes": [
"30",
"209",
"1730"
],
"creator_email": [
"hello@hello.com"
],
"price": [
"3.0"
],
"name": [
"Video Motion Apple"
],
"creator_name": [
"Creator"
],
"id": [
"291"
]
}
},
.............
]
}
}


결과중 짜증나는건, Field Type 이 Array 가 아닌것들도 Array 로 온다.........





'AWS > CloudSearch' 카테고리의 다른 글

[CloudSearch] Java SDK 사용하여 Search 하기  (0) 2016.03.29
[CloudSearch] Java SDK 로 document update  (0) 2016.03.28
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



AWS CloudSearch



Java SDK 연동하는 CloudSearch 관련 문서가 없는거 같다. 


1. Document Update(JSON)


- Domain

@Setter
@Getter
@ToString
public class SearchDocument {
private String id;
private String type;
private SearchItem fields;
}


@Setter
@Getter
@ToString
public class SearchItem {
String id;
private String name;
String description;
String price;
String thumbnail;
Long fileSize;
String fileExtensions;
String creatorName;
String creatorEmail;
SearchItemKind kind;
String happenedDate;
String[] categoryNames;
Long[] categoryCodes;
}



- 위 Domain 을 JSON 으로 변환한 것

각 Object 최상위에 id 와 type, fields 는 필수로 존재해야 한다.

type 값에는 add, delete 두가지가 있다.

각 field type 에 허용되는 값에 대한 설명은 아래

http://docs.aws.amazon.com/cloudsearch/latest/developerguide/configuring-index-fields.html

[
{
"id": "Marketplace_292",
"type": "add",
"fields": {
"id": "292",
"name": "Motion Graphics",
"description": "Motion Graphics description",
"price": "6.12",
"thumbnail": "http://**********/edbeb3e0-7c8c-4319-849b-863087f272c8.jpg",
"file_size": 21798,
"file_extensions": "jpg,png",
"creator_name": "hello",
"creator_email": "hello@hello.com",
"kind": "Marketplace",
"happened_date":"2016-03-26T05:12:32.545Z",
"category_names": [
"Video Motion",
"Motion Graphics",
"Overlays"
],
"category_codes": [
30,
210,
1775
]
}
}
]



Java Code


AmazonCloudSearchDomainClient domain
= new AmazonCloudSearchDomainClient(S3Manager.getCredentials());
domain.setEndpoint("********");

Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();

String str = gson.toJson(getSearchDocuments());

byte[] bytes = str.getBytes("UTF-8");

InputStream is = new ByteArrayInputStream(bytes);

UploadDocumentsRequest req = new UploadDocumentsRequest();
req.setContentType(ContentType.Applicationjson);
req.setDocuments(is);
req.setContentLength(0L + bytes.length);

UploadDocumentsResult result = domain.uploadDocuments(req);




'AWS > CloudSearch' 카테고리의 다른 글

[CloudSearch] Java SDK 사용하여 Search 하기  (0) 2016.03.29
[CloudSearch] Java SDK 로 document update  (0) 2016.03.28
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST




AngularJS


Angular 튜토리얼을 그냥 하나씩 진행하겠습니다.  Jasmine 은 패스 


angular.js 및 정식 튜토리얼은 위 이미지 클릭 - API


역시나 IE는 쓰레기, IE7,8,9에서 작은(?) 문제가 있으며, 해결책은 맨아래





1.  값 바인딩


index.html

  1. <html ng-app>
  2. <head>
  3. ...
  4. <script src="lib/angular/angular.js"></script>
  5. <script src="js/controllers.js"></script>
  6. </head>
  7. <body ng-controller="PhoneListCtrl">
  8.  
  9. <ul>
  10. <li ng-repeat="phone in phones">
  11. {{phone.name}}
  12. <p>{{phone.snippet}}</p>
  13. </li>
  14. </ul>
  15. </body>
  16. </html>



controllers.js

  1. function PhoneListCtrl($scope) {
  2. $scope.phones = [
  3. {"name": "Nexus S",
  4. "snippet": "Fast just got faster with Nexus S."},
  5. {"name": "Motorola XOOM™ with Wi-Fi",
  6. "snippet": "The Next, Next Generation tablet."},
  7. {"name": "MOTOROLA XOOM™",
  8. "snippet": "The Next, Next Generation tablet."}
  9. ];
  10. }



동작 

심플!


<html> 태그에 ng-app 를 추가하여 angular application 이라고 선언해준다.


 그리고 컨트롤러가 적용될 태그에 ng-controller="PhoneListCtrl" 를 추가한다.


컨트롤러에 들어갈 값은 controllers.js 에 함수로 정의한 함수명이 그대로 사용된다. 

body가 refresh 등 어떤 이유로 변경되었을 경우에 지정한 컨트롤러가 날아가는데

그걸 방지하기위해 컨트롤러를 html 태그안에 선언해도 된다.



그다음 리스트류를 표현할때

li 에 다가 ng-repeat="phone in phones" 선언하면

foreach 나 each 처럼 사용이 된다.


 phones 를 $scope에 정의해주면

해당 컨트롤러의 scope 내에서 사용할 수 있다.




2. search


index.html

  1. <div class="container-fluid">
  2. <div class="row-fluid">
  3. <div class="span2">
  4. <!--Sidebar content-->
  5.  
  6. Search: <input ng-model="query123">
  7.  
  8. </div>
  9. <div class="span10">
  10. <!--Body content-->
  11.  
  12. <ul class="phones">
  13. <li ng-repeat="phone in phones | filter:query123">
  14. {{phone.name}}
  15. <p>{{phone.snippet}}</p>
  16. </li>
  17. </ul>
  18.  
  19. </div>
  20. </div>
  21. </div>



동작

ng-model="query123" 


이라고 input 에다가 선언을 하였습니다.


그럼 해당 input 에 입력되는 text는 query123 이라는 바인딩변수로 사용 할 수 있습니다.


문서 아무곳이나 <div> {{query123}} </div> 라고 해놓았다면


input 에 글자를 입력되는 순간 저 div 에도 동일하게 해당 text가 나오게 됩니다. 


돌아가서 13라인에 필터라고 선언하고 query123을 지정했습니다.


그러면 글자가 입력되는 순간 해당 li에 모든 텍스트중 동일한 글자가 있는지를 검색하여


동일한 글자가 있는 li만 리스트에 보여주게 됩니다.


만약 phone.name 이나, phone.snippet 어느 하나에만 적용하고 싶을때는 


ng-model = "query123.name"  이나 query123.snippet 으로 해주시고 필터에는 그냥 query123 그대로 주면


해당 값에만 필터가 걸립니다.


만약 10개중 2개에서만 필터를 하고 싶을경우는


해당 controller.js 에


 $scope.queryFilter = function(list){

 return list.name.toLowerCase().search($scope.query) != -1

        || list.snippet.toLowerCase().search($scope.query) != -1;

  }


아래와 같이 합니다. 대소문자 구분을 짓고싶으면 toLowerCase 를 빼면되겠죠






3. Sort


index.html

  1. Search: <input ng-model="query">

  2. Sort by:
  3. <select ng-model="orderProp">
  4. <option value="name">Alphabetical</option>
  5. <option value="age">Newest</option>
  6. </select>
  7.  
  8.  
  9. <ul class="phones">
  10. <li ng-repeat="phone in phones | filter:query | orderBy:orderProp">
  11. {{phone.name}}
  12. <p>{{phone.snippet}}</p>
  13. </li>
  14. </ul>



controllers.js

  1. function PhoneListCtrl($scope) {
  2. $scope.phones = [
  3. {"name": "Nexus S",
  4. "snippet": "Fast just got faster with Nexus S.",
  5. "age": 0},
  6. {"name": "Motorola XOOM™ with Wi-Fi",
  7. "snippet": "The Next, Next Generation tablet.",
  8. "age": 1},
  9. {"name": "MOTOROLA XOOM™",
  10. "snippet": "The Next, Next Generation tablet.",
  11. "age": 2}
  12. ];
  13.  
  14. $scope.orderProp = 'age';
  15. }



동작

이번엔 select 에다가 ng-model 을 선언했습니다.


그러면 선택되는 option 의 value가 model의 값이 됩니다.


그러면 index.html 의 11 라인 orderBy:orderProp"  으로 선언해주면 


해당 리스트는 선택된 orderProp 의 값 name, age 중 하나로 정렬하게 됩니다.


controllers.js에 key 인 name과 age중 하나를 선택하게 됩니다.


14라인에서 값을 'age'로 주고 있습니다.


그러면 select box는 해당 값으로 선택이 되어 있는 상태로 렌더링되고, 리스트도 적용되어 보이게 됩니다.






4. XHR


phones.json

  1. [
  2. {
  3. "age": 13,
  4. "id": "motorola-defy-with-motoblur",
  5. "name": "Motorola DEFY\u2122 with MOTOBLUR\u2122",
  6. "snippet": "Are you ready for everything life throws your way?"
  7. ...
  8. },
  9. ...
  10. ]


controllers.js

  1. function PhoneListCtrl($scope, $http) {
  2. $http.get('phones/phones.json').success(function(data) {
  3. $scope.phones = data;
  4. });
  5.  
  6. $scope.orderProp = 'age';
  7. }
  8.  
  9. //PhoneListCtrl.$inject = ['$scope', '$http'];



동작

$http.get 으로 파일을 가져오고 있습니다. 

다른메소드로는

$http.get, $http.head$http.post$http.put$http.delete$http.jsonp 가 있습니다. API 참조하세요 


그리고 controllers.js 에 주석처리된 놈은 Depedency Injection입니다.

원하면 컨트롤러에 직접 필요한 인자를 집어넣어 줄 수 있습니다.


그리고 controllers.js 라인 3 - data를 


$scope.phones = data.splice(0, 5);


같이 원하는만큼만 넣으셔도됩니다.


계속 됩니다.




※ IE 에서 바인딩이 되지 않고, 그대로 {{name}} 이 나올 때,JSON.strigify 가 안되거나, 

     등등의 문제를 위한 작은 해결책


1. doctype이 저렇게 되어있지않다면 바꿔보세요.

<!doctype html>


2.

<html lang="en" class="ng-app:myapp" id="ng-app" ng-app="myapp" xmlns:ng="http://angularjs.org">

     <head>    

        <!--[if lt IE 9]>

          <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>

        <![endif]-->

        <!--[if lte IE 8]>

          <script>

            document.createElement('ng-include');

            document.createElement('ng-pluralize');

            document.createElement('ng-view');

            document.createElement('ng:include');

            document.createElement('ng:pluralize');

            document.createElement('ng:view');

          </script>

        <![endif]-->

        <!--[if lt IE 8]>

          <script src="js/json2.js"></script>

        <![endif]-->

      </head>


'Javascript > AngularJS' 카테고리의 다른 글

[tutorial] AngularJS 튜토리얼 - 1  (0) 2013.01.03
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST