Skip to content

Commit 3d024be

Browse files
authored
Merge pull request #428 from keillera/ALIS-5769
Add users_articles_popular.
2 parents 6ae0307 + d714383 commit 3d024be

File tree

7 files changed

+527
-2
lines changed

7 files changed

+527
-2
lines changed

database-template.yaml

+11-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Resources:
1717
AttributeType: N
1818
- AttributeName: sync_elasticsearch
1919
AttributeType: N
20+
- AttributeName: popular_sort_key
21+
AttributeType: N
2022
KeySchema:
2123
- AttributeName: article_id
2224
KeyType: HASH
@@ -51,6 +53,14 @@ Resources:
5153
KeyType: HASH
5254
Projection:
5355
ProjectionType: ALL
56+
- IndexName: user_id-popular_sort_key-index
57+
KeySchema:
58+
- AttributeName: user_id
59+
KeyType: HASH
60+
- AttributeName: popular_sort_key
61+
KeyType: RANGE
62+
Projection:
63+
ProjectionType: ALL
5464
BillingMode: PAY_PER_REQUEST
5565
ArticleContent:
5666
Type: AWS::DynamoDB::Table
@@ -765,4 +775,4 @@ Resources:
765775
KeyType: RANGE
766776
BillingMode: PAY_PER_REQUEST
767777
SSESpecification:
768-
SSEEnabled: true
778+
SSEEnabled: true

database.yaml

+14-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Resources:
1313
AttributeType: N
1414
- AttributeName: sync_elasticsearch
1515
AttributeType: N
16+
- AttributeName: popular_sort_key
17+
AttributeType: N
1618
KeySchema:
1719
- AttributeName: article_id
1820
KeyType: HASH
@@ -59,6 +61,17 @@ Resources:
5961
ProvisionedThroughput:
6062
ReadCapacityUnits: 2
6163
WriteCapacityUnits: 2
64+
- IndexName: user_id-popular_sort_key-index
65+
KeySchema:
66+
- AttributeName: user_id
67+
KeyType: HASH
68+
- AttributeName: popular_sort_key
69+
KeyType: RANGE
70+
Projection:
71+
ProjectionType: ALL
72+
ProvisionedThroughput:
73+
ReadCapacityUnits: 2
74+
WriteCapacityUnits: 2
6275
ProvisionedThroughput:
6376
ReadCapacityUnits: 2
6477
WriteCapacityUnits: 2
@@ -872,4 +885,4 @@ Resources:
872885
ReadCapacityUnits: 1
873886
WriteCapacityUnits: 1
874887
SSESpecification:
875-
Enabled: true
888+
Enabled: true

function02-template.yaml

+20
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,22 @@ Resources:
250250
Timeout: 900
251251
TracingConfig:
252252
Mode: "Active"
253+
UsersArticlesPopular:
254+
Type: "AWS::Lambda::Function"
255+
Properties:
256+
Code: ./deploy/users_articles_popular.zip
257+
Environment:
258+
Variables:
259+
ARTICLE_INFO_TABLE_NAME: !Ref ArticleInfoTableName
260+
Handler: handler.lambda_handler
261+
MemorySize: 3008
262+
Role:
263+
Fn::ImportValue:
264+
Fn::Sub: "${AlisAppId}-LambdaRole"
265+
Runtime: python3.6
266+
Timeout: 900
267+
TracingConfig:
268+
Mode: "Active"
253269
UsersWalletAddressShow:
254270
Type: "AWS::Lambda::Function"
255271
Properties:
@@ -316,3 +332,7 @@ Outputs:
316332
Value: !GetAtt UsersWalletAddressShow.Arn
317333
Export:
318334
Name: !Sub "${AlisAppId}-UsersWalletAddressShow"
335+
UsersArticlesPopular:
336+
Value: !GetAtt UsersArticlesPopular.Arn
337+
Export:
338+
Name: !Sub "${AlisAppId}-UsersArticlesPopular"

src/common/settings.py

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
'minimum': 1,
77
'maximum': 100
88
},
9+
'popular_sort_key': {
10+
'type': 'number',
11+
'minimum': 0,
12+
'maximum': 10 ** 30
13+
},
914
'article_id': {
1015
'type': 'string',
1116
'minLength': 12,
@@ -281,6 +286,7 @@
281286
ARTICLES_TIP_RAKING_DEFAULT_LIMIT = 20
282287

283288
USERS_ARTICLE_INDEX_DEFAULT_LIMIT = 10
289+
USERS_ARTICLE_POPULAR_INDEX_DEFAULT_LIMIT = 3
284290
NOTIFICATION_INDEX_DEFAULT_LIMIT = 10
285291
COMMENT_INDEX_DEFAULT_LIMIT = 10
286292
TAG_SEARCH_DEFAULT_LIMIT = 100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# -*- coding: utf-8 -*-
2+
import boto3
3+
from users_articles_popular import UsersArticlesPopular
4+
5+
dynamodb = boto3.resource('dynamodb')
6+
7+
8+
def lambda_handler(event, context):
9+
users_articles_popular = UsersArticlesPopular(event, context, dynamodb)
10+
return users_articles_popular.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import os
2+
import json
3+
import settings
4+
from lambda_base import LambdaBase
5+
from boto3.dynamodb.conditions import Key, Attr
6+
from jsonschema import validate
7+
from decimal_encoder import DecimalEncoder
8+
from parameter_util import ParameterUtil
9+
10+
11+
class UsersArticlesPopular(LambdaBase):
12+
def get_schema(self):
13+
return {
14+
'type': 'object',
15+
'properties': {
16+
'user_id': settings.parameters['user_id'],
17+
'limit': settings.parameters['limit'],
18+
'article_id': settings.parameters['article_id'],
19+
'popular_sort_key': settings.parameters['popular_sort_key']
20+
},
21+
'required': ['user_id']
22+
}
23+
24+
def validate_params(self):
25+
ParameterUtil.cast_parameter_to_int(self.params, self.get_schema())
26+
validate(self.params, self.get_schema())
27+
28+
def exec_main_proc(self):
29+
article_info_table = self.dynamodb.Table(os.environ['ARTICLE_INFO_TABLE_NAME'])
30+
limit = UsersArticlesPopular.get_index_limit(self.params)
31+
32+
query_params = {
33+
'Limit': limit,
34+
'IndexName': 'user_id-popular_sort_key-index',
35+
'KeyConditionExpression': Key('user_id').eq(self.params['user_id']),
36+
'FilterExpression': Attr('status').eq('public'),
37+
'ScanIndexForward': False
38+
}
39+
40+
if UsersArticlesPopular.require_last_evaluated_key(self.params):
41+
last_evaluated_key = {
42+
'user_id': self.params['user_id'],
43+
'article_id': self.params['article_id'],
44+
'popular_sort_key': int(self.params['popular_sort_key'])
45+
}
46+
47+
query_params.update({'ExclusiveStartKey': last_evaluated_key})
48+
49+
response = article_info_table.query(**query_params)
50+
51+
items = response['Items']
52+
53+
while 'LastEvaluatedKey' in response and len(response['Items']) < limit:
54+
query_params.update({'ExclusiveStartKey': response['LastEvaluatedKey']})
55+
response = article_info_table.query(**query_params)
56+
items.extend(response['Items'])
57+
58+
if len(items) >= limit:
59+
last_evaluated_key = {
60+
'user_id': self.params['user_id'],
61+
'article_id': items[limit - 1]['article_id'],
62+
'popular_sort_key': int(items[limit - 1]['popular_sort_key'])
63+
}
64+
response.update({'LastEvaluatedKey': last_evaluated_key})
65+
break
66+
67+
response['Items'] = items[:limit]
68+
69+
return {
70+
'statusCode': 200,
71+
'body': json.dumps(response, cls=DecimalEncoder)
72+
}
73+
74+
@staticmethod
75+
def get_index_limit(params):
76+
if params is not None and params.get('limit') is not None:
77+
return int(params.get('limit'))
78+
else:
79+
return settings.USERS_ARTICLE_POPULAR_INDEX_DEFAULT_LIMIT
80+
81+
@staticmethod
82+
def require_last_evaluated_key(params):
83+
if params.get('article_id') is not None and params.get('popular_sort_key') is not None:
84+
return True
85+
return False

0 commit comments

Comments
 (0)