質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

firebaseにおける期間別いいね集計機能について

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 179

kO2ke

score 1

firebaseを利用して、投稿のいいね数を、年別、月別、日別に例えばランキングなどのために集計したいと考えています

普通に考えれば、投稿のサブコレクションにいいねに作成時間を加えたものを記録していき、where句の指定の期間の範囲で絞り込めば、ある投稿に対する特定の期間のいいねを抽出できると思います。

/posts/:id/likes/:userid

interface Like {
 userId: string;
 createdAt: db.timestamp;
}
db.collections("posts").doc(id).collections("likes")
 .where(createdAt, ">=", starttime)
 .where(createdAt, "<=", endtime)
 .get()

しかし、たとえば今月や先週の言い値の数などでorderbyしてランキングを実装しようと思うと一度すべての投稿の特定期間のいいねを取得して、それをクライアントサイドでソートするという作業が必要になります。

そこで、likeStatistics というルートコレクションを作成し

//2020年1月1日のデータ階層

likeStatistics
└─years
    └─2020
        ├─months
        │  └─1
        │      ├─posts
        │      │  └─postid
        │      └─weeks
        │          └─1
        │              ├─days
        │              │  └─1
        │              │      └─posts
        │              │          └─postid
        │              └─posts
        │                  └─postid
        └─posts
            └─postid

ある日時にいいねされた場合に

//likeStatistics/../posts/:postid
interface PostState{
 post: db.DocumentReference;
  likeCount: number;
}


const today = new Date()
const year:  string  = 年 
const month: string  = 月
const week:  string  = 第何週
const date:  string  = 日

const postRef = db.collection("posts").doc(postId)

//年別のいいねを加算
db.collections("likeStatistics")
 .doc(year)
 .collection("posts")
 .doc(postid)
 .update({likeCount: db.FieltValue.increment(1)})

//月別のいいねを加算
db.collections("likeStatistics")
 .doc(year)
 .collection("months")
 .doc(month)
 .collection("post")
 .doc(postid)
 .update({likeCount: db.FieltValue.increment(1)})

//週別のいいねを加算
db.collections("likeStatistics")
.doc(year)
.collection("months")
.doc(month)
.collection("weeks")
.doc(week)
.collection("post")
.doc(postid)
.update({likeCount: db.FieltValue.increment(1)})

//日別のいいねを加算
db.collections("likeStatistics")
.doc(year)
.collection("months")
.doc(month)
.collection("weeks")
.doc(week)
.collection("dates")
.doc(date)
.collection("post")
.doc(postid)
.update({likeCount: db.FieltValue.increment(1)})

というように、year, month, week, dayドキュメントのすべてのposts/:postidのlikeCountを加算すれば、
例えば2020年1月のいいね数TOP10は

db.collections("likeStatistics")
 .doc(2020)
 .collection("months")
 .doc(1)
 .collection("posts")
 .orderby("likeCount", "desc")
 .limit(10)
 .get()


で10個のリファレンスを取得して、それらをルートのpostsから本データを抽出するのが簡単にできると思いました

この設計は妥当でしょうか?
それとも前者の設計でCloud FunctionsでAPIを作ったほうがよいでしょうか?

ご意見やご指導願います。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る