2016-09-15 78 views
0

我正在運行一個每X分鐘運行一次的cronjob,以瞭解最受歡迎的標籤是什麼(hashtags)。我Elasticsearch存儲用戶活動Fluentd,所以說對於用戶搜索字詞,將被存儲在elasticsearch像這樣:如何使用spring elasticsearch來計算字段發生的次數?

{ activity: "search", user: X, searchTerm: "XYZ"} 

我有一個活動標籤。用戶每次搜索標籤時,都會將其插入爲活動。通過這種方式,我可以找出用戶喜歡的標籤以及總體上找到最受歡迎的標籤。

這裏是我的ES的結構:

{ 
    "_index":"user_activity", 
    "_type":"user_activity", 
    "_id":"AVcokbsXKR86Bn8FzoFU", 
    "_score":1.0, 
    "_source":{ 
     "user":{ 
      "userId":4, 
      "name":"Another one", 
     }, 
     "activity":"CREATE", 
     "date":1473854418419, 
     "article":{ 
      {user who posted article...} 
      ... Article data (title, etc...) 
      // Tags associated to this article 
      "tags":[ 
       { 
        "tagId":23, 
        "tagName":"randomTagName" 
       } 
      ], 
     }, 
    } 
}, 
{ 
    "_index":"user_activity", 
    "_type":"user_activity", 
    "_id":"AVcomLEnKR86Bn8FzoFu", 
    "_score":1.0, 
    "_source":{ 
     "user":{ 
      "userId":1, 
      "name":"MEATTTT DAMOENNNN", 
     }, 
     "activity":"TAG_SEARCH", 
     "date":1473854873951, 
     "tag":"photos" 
    } 
} 
... There can be different types of activities 

正如你可以看到有不同的活動類型。我試圖查詢ES並讓它返回每個唯一標籤的總搜索量。如果您看到TAG_SEARCH對象,則可以看到它有一個字段標籤。我正在嘗試爲唯一標記值找到TAG_SEARCH活動的總金額!

這是我試過使用NativeSearchQueryBuilder

SearchQuery searchQuery = new NativeSearchQueryBuilder() 
       .withQuery(matchAllQuery()) 
       .withSearchType(COUNT) 
       .withIndices("user_activity").withTypes("user_activity") 
       .addAggregation(terms("activity").field("activity")) 

這樣做是返回文件總金額爲每個唯一活動值。因此,對於上述JSON的結果將是:

"buckets" : [ { 
     "key" : "create", 
     "doc_count" : 1 
     }, { 
     "key" : "tag_search", 
     "doc_count" : 1 
     } 
] 

但是我想要得到的是:

"buckets" : [ { 
      "key" : "tag", 
      "value": "TagNameGoesHere", 
      "doc_count" : 4 
      }, { 
      "key" : "tag", 
      "value": "AnotherTagNameGoesHere", 
      "doc_count" : 10 
      } 
    ] 

我怎樣才能找出獨特標籤的總數:X值其中活動:TAG_SEARCH

我期望的SEARCHQUERY看起來是這樣的:

SearchQuery searchQuery = new NativeSearchQueryBuilder() 
        .withQuery(matchAllQuery()) 
        .withSearchType(COUNT) 
        .withIndices("user_activity").withTypes("user_activity") 
        .addAggregation(terms("activity").value("TAG_SEARCH")) 
        .addAggregation(terms("tag")) // Count no docs per tag 

回答

3

您只需在activity現場查詢,然後在tag領域聚集。

SearchQuery searchQuery = new NativeSearchQueryBuilder() 
     .withQuery(QueryBuilders.matchQuery("activity", "TAG_SEARCH")) 
     .withSearchType(COUNT) 
     .withIndices("user_activity") 
     .withTypes("user_activity") 
     .addAggregation(AggregationBuilders.terms("tags").field("tag")); 

相應的原始JSON查詢會是這樣一個

POST user_activity/user_activity/_search?search_type=count 
{ 
    "query": { 
    "match": { 
     "activity": "TAG_SEARCH" 
    } 
    }, 
    "aggs": { 
    "tags": { 
     "terms": { 
     "field": "tag" 
     } 
    } 
    } 
} 
+0

啊完美。我對ES很新,不得不用它來實現這個Java api很難 – James111

+0

太棒了,很高興它幫助了! – Val