topviewed-removed-queries-fixes

This commit is contained in:
tonyrewin 2022-09-20 10:11:22 +03:00
parent a67725a634
commit e41856dbc3
4 changed files with 44 additions and 58 deletions

View File

@ -52,7 +52,6 @@ from resolvers.zine import (
recent_all, recent_all,
recent_commented, recent_commented,
recent_reacted, recent_reacted,
top_viewed,
shouts_by_authors, shouts_by_authors,
shouts_by_topics, shouts_by_topics,
shouts_by_communities, shouts_by_communities,
@ -84,7 +83,6 @@ __all__ = [
"get_user_reacted_shouts", "get_user_reacted_shouts",
"top_month", "top_month",
"top_overall", "top_overall",
"top_viewed",
"increment_view", "increment_view",
"get_shout_by_slug", "get_shout_by_slug",
# editor # editor

View File

@ -18,16 +18,11 @@ from services.zine.shoutscache import ShoutsCache
@mutation.field("incrementView") @mutation.field("incrementView")
async def increment_view(_, _info, shout): async def increment_view(_, _info, shout):
# TODO: use ackee to collect views
async with ViewedStorage.lock: async with ViewedStorage.lock:
return ViewedStorage.increment(shout) return ViewedStorage.increment(shout)
@query.field("topViewed")
async def top_viewed(_, _info, offset, limit):
async with ShoutsCache.lock:
return ShoutsCache.top_viewed[offset : offset + limit]
@query.field("topMonth") @query.field("topMonth")
async def top_month(_, _info, offset, limit): async def top_month(_, _info, offset, limit):
async with ShoutsCache.lock: async with ShoutsCache.lock:

View File

@ -229,7 +229,6 @@ type Query {
shoutsByAuthors(slugs: [String]!, offset: Int!, limit: Int!): [Shout]! shoutsByAuthors(slugs: [String]!, offset: Int!, limit: Int!): [Shout]!
shoutsByCommunities(slugs: [String]!, offset: Int!, limit: Int!): [Shout]! shoutsByCommunities(slugs: [String]!, offset: Int!, limit: Int!): [Shout]!
myCandidates(offset: Int!, limit: Int!): [Shout]! # test myCandidates(offset: Int!, limit: Int!): [Shout]! # test
topViewed(offset: Int!, limit: Int!): [Shout]!
# topReacted(offset: Int!, limit: Int!): [Shout]! # topReacted(offset: Int!, limit: Int!): [Shout]!
topAuthors(offset: Int!, limit: Int!): [Author]! topAuthors(offset: Int!, limit: Int!): [Author]!
topMonth(offset: Int!, limit: Int!): [Shout]! # TODO: rename topRatedMonth topMonth(offset: Int!, limit: Int!): [Shout]! # TODO: rename topRatedMonth

View File

@ -1,19 +1,19 @@
import asyncio import asyncio
from datetime import datetime, timedelta from datetime import datetime, timedelta
from sqlalchemy import desc, func, select from sqlalchemy import and_, desc, func, select
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from base.orm import local_session from base.orm import local_session
from orm.reaction import Reaction from orm.reaction import Reaction, ReactionKind
from orm.shout import Shout, ShoutAuthor, ShoutTopic from orm.shout import Shout, ShoutAuthor, ShoutTopic
from services.stat.viewed import ViewedByDay, ViewedStorage
from services.stat.reacted import ReactedStorage from services.stat.reacted import ReactedStorage
async def get_shout_stat(slug): async def get_shout_stat(slug):
return { return {
"viewed": await ViewedStorage.get_shout(slug), # TODO: use ackee as datasource
"viewed": 0, # await ViewedStorage.get_shout(slug),
"reacted": len(await ReactedStorage.get_shout(slug)), "reacted": len(await ReactedStorage.get_shout(slug)),
"commented": len(await ReactedStorage.get_comments(slug)), "commented": len(await ReactedStorage.get_comments(slug)),
"rating": await ReactedStorage.get_rating(slug), "rating": await ReactedStorage.get_rating(slug),
@ -22,6 +22,7 @@ async def get_shout_stat(slug):
async def prepare_shouts(session, stmt): async def prepare_shouts(session, stmt):
shouts = [] shouts = []
print(stmt)
for s in list(map(lambda r: r.Shout, session.execute(stmt))): for s in list(map(lambda r: r.Shout, session.execute(stmt))):
s.stat = await get_shout_stat(s.slug) s.stat = await get_shout_stat(s.slug)
shouts.append(s) shouts.append(s)
@ -39,7 +40,6 @@ class ShoutsCache:
recent_commented = [] recent_commented = []
top_month = [] top_month = []
top_overall = [] top_overall = []
top_viewed = []
top_commented = [] top_commented = []
by_author = {} by_author = {}
@ -56,7 +56,8 @@ class ShoutsCache:
selectinload(Shout.authors), selectinload(Shout.authors),
selectinload(Shout.topics) selectinload(Shout.topics)
) )
.where(bool(Shout.publishedAt)) .where(Shout.deletedAt.is_(None))
.filter(Shout.publishedAt.is_not(None))
.order_by(desc("publishedAt")) .order_by(desc("publishedAt"))
.limit(ShoutsCache.limit) .limit(ShoutsCache.limit)
), ),
@ -76,9 +77,10 @@ class ShoutsCache:
selectinload(Shout.authors), selectinload(Shout.authors),
selectinload(Shout.topics) selectinload(Shout.topics)
) )
.where(Shout.deletedAt.is_(None))
.order_by(desc("createdAt")) .order_by(desc("createdAt"))
.limit(ShoutsCache.limit) .limit(ShoutsCache.limit)
), )
) )
async with ShoutsCache.lock: async with ShoutsCache.lock:
ShoutsCache.recent_all = shouts[0:ShoutsCache.limit] ShoutsCache.recent_all = shouts[0:ShoutsCache.limit]
@ -94,15 +96,18 @@ class ShoutsCache:
shouts = await prepare_shouts( shouts = await prepare_shouts(
session, session,
( (
select(Shout, Reaction.createdAt.label('reactedAt')) select(
Shout,
Reaction.createdAt.label('reactedAt')
)
.options( .options(
selectinload(Shout.authors), selectinload(Shout.authors),
selectinload(Shout.topics), selectinload(Shout.topics),
selectinload(Shout.reactions), selectinload(Shout.reactions),
) )
.join(Reaction) .join(Reaction)
.where(Shout.slug.in_(reacted_slugs)) .where(and_(Shout.deletedAt.is_(None), Shout.slug.in_(reacted_slugs)))
.filter(bool(Shout.publishedAt)) .filter(Shout.publishedAt.is_not(None))
.group_by(Shout.slug, "reactedAt") .group_by(Shout.slug, "reactedAt")
.order_by(desc("reactedAt")) .order_by(desc("reactedAt"))
.limit(ShoutsCache.limit) .limit(ShoutsCache.limit)
@ -123,15 +128,17 @@ class ShoutsCache:
shouts = await prepare_shouts( shouts = await prepare_shouts(
session, session,
( (
select(Shout, Reaction.createdAt.label('reactedAt')) select(
Shout,
Reaction.createdAt.label('reactedAt')
)
.options( .options(
selectinload(Shout.authors), selectinload(Shout.authors),
selectinload(Shout.topics), selectinload(Shout.topics),
selectinload(Shout.reactions), selectinload(Shout.reactions),
) )
.join(Reaction, Reaction.shout == Shout.slug) .join(Reaction)
.where(Shout.slug.in_(commented_slugs)) .where(and_(Shout.deletedAt.is_(None), Shout.slug.in_(commented_slugs)))
.filter(bool(Shout.publishedAt))
.group_by(Shout.slug, "reactedAt") .group_by(Shout.slug, "reactedAt")
.order_by(desc("reactedAt")) .order_by(desc("reactedAt"))
.limit(ShoutsCache.limit) .limit(ShoutsCache.limit)
@ -147,15 +154,20 @@ class ShoutsCache:
shouts = await prepare_shouts( shouts = await prepare_shouts(
session, session,
( (
select(Shout) select(
Shout,
func.sum(int(bool(Reaction.kind == ReactionKind.LIKE))).label('liked')
)
.options( .options(
selectinload(Shout.authors), selectinload(Shout.authors),
selectinload(Shout.topics), selectinload(Shout.topics),
selectinload(Shout.reactions), selectinload(Shout.reactions),
) )
.join(Reaction) .join(Reaction)
.where(bool(Shout.publishedAt)) .where(Shout.deletedAt.is_(None))
.filter(Shout.publishedAt.is_not(None))
.group_by(Shout.slug) .group_by(Shout.slug)
.order_by(desc("liked"))
.limit(ShoutsCache.limit) .limit(ShoutsCache.limit)
), ),
) )
@ -171,15 +183,20 @@ class ShoutsCache:
shouts = await prepare_shouts( shouts = await prepare_shouts(
session, session,
( (
select(Shout) select(
Shout,
func.sum(int(bool(Reaction.kind == ReactionKind.LIKE))).label('liked')
)
.options( .options(
selectinload(Shout.authors), selectinload(Shout.authors),
selectinload(Shout.topics), selectinload(Shout.topics),
selectinload(Shout.reactions), selectinload(Shout.reactions),
) )
.join(Reaction) .join(Reaction)
.where(Shout.publishedAt > month_ago) .where(Shout.deletedAt.is_(None))
.filter(Shout.publishedAt > month_ago)
.group_by(Shout.slug) .group_by(Shout.slug)
.order_by(desc("liked"))
.limit(ShoutsCache.limit) .limit(ShoutsCache.limit)
), ),
) )
@ -195,14 +212,18 @@ class ShoutsCache:
shouts = await prepare_shouts( shouts = await prepare_shouts(
session, session,
( (
select(Shout, func.sum(int(bool(Reaction.body))).label("commented")) select(
Shout,
func.sum(int(bool(Reaction.body))).label("commented")
)
.options( .options(
selectinload(Shout.authors), selectinload(Shout.authors),
selectinload(Shout.topics), selectinload(Shout.topics),
selectinload(Shout.reactions) selectinload(Shout.reactions)
) )
.join(Reaction) .join(Reaction)
.filter(Shout.createdAt > month_ago) .where(Shout.deletedAt.is_(None))
.filter(Shout.publishedAt > month_ago)
.group_by(Shout.slug) .group_by(Shout.slug)
.order_by(desc("commented")) .order_by(desc("commented"))
.limit(ShoutsCache.limit) .limit(ShoutsCache.limit)
@ -213,38 +234,12 @@ class ShoutsCache:
ShoutsCache.top_commented = shouts ShoutsCache.top_commented = shouts
print("[zine.cache] %d last month top commented shouts " % len(ShoutsCache.top_commented)) print("[zine.cache] %d last month top commented shouts " % len(ShoutsCache.top_commented))
@staticmethod
async def prepare_top_viewed():
month_ago = datetime.now() - timedelta(days=30)
with local_session() as session:
shouts = await prepare_shouts(
session,
(
select(Shout, func.sum(ViewedByDay.value).label("viewed"))
.options(
selectinload(Shout.authors),
selectinload(Shout.topics),
selectinload(Shout.reactions)
)
.join(Reaction)
.join(ViewedByDay, ViewedByDay.shout == Shout.slug)
.filter(Shout.createdAt > month_ago)
.group_by(Shout.slug)
.order_by(desc("viewed"))
.limit(ShoutsCache.limit)
)
)
shouts.sort(key=lambda s: s.stat["viewed"], reverse=True)
async with ShoutsCache.lock:
print("[zine.cache] %d last month top viewed shouts " % len(shouts))
ShoutsCache.top_viewed = shouts
@staticmethod @staticmethod
async def prepare_by_author(): async def prepare_by_author():
shouts_by_author = {} shouts_by_author = {}
with local_session() as session: with local_session() as session:
for a in session.query(ShoutAuthor).all(): for a in session.query(ShoutAuthor).all():
shout = session.query(Shout).filter(Shout.slug == a.shout).first() shout = session.query(Shout).where(Shout.slug == a.shout).first()
shout.stat = await get_shout_stat(shout.slug) shout.stat = await get_shout_stat(shout.slug)
shouts_by_author[a.user] = shouts_by_author.get(a.user, []) shouts_by_author[a.user] = shouts_by_author.get(a.user, [])
if shout not in shouts_by_author[a.user]: if shout not in shouts_by_author[a.user]:
@ -258,7 +253,7 @@ class ShoutsCache:
shouts_by_topic = {} shouts_by_topic = {}
with local_session() as session: with local_session() as session:
for a in session.query(ShoutTopic).all(): for a in session.query(ShoutTopic).all():
shout = session.query(Shout).filter(Shout.slug == a.shout).first() shout = session.query(Shout).where(Shout.slug == a.shout).first()
shout.stat = await get_shout_stat(shout.slug) shout.stat = await get_shout_stat(shout.slug)
shouts_by_topic[a.topic] = shouts_by_topic.get(a.topic, []) shouts_by_topic[a.topic] = shouts_by_topic.get(a.topic, [])
if shout not in shouts_by_topic[a.topic]: if shout not in shouts_by_topic[a.topic]:
@ -273,7 +268,6 @@ class ShoutsCache:
try: try:
await ShoutsCache.prepare_top_month() await ShoutsCache.prepare_top_month()
await ShoutsCache.prepare_top_overall() await ShoutsCache.prepare_top_overall()
await ShoutsCache.prepare_top_viewed()
await ShoutsCache.prepare_top_commented() await ShoutsCache.prepare_top_commented()
await ShoutsCache.prepare_recent_published() await ShoutsCache.prepare_recent_published()