Cloud Firestore orderBy 제한: 범위에서 얻은 값과 다른 항목으로 정렬할 수 없음

9687 단어 FirebaseFirestore

소개



지난 주부터 웹 앱을 만들고 있습니다.
nuxt.js로 4 월부터 초등학생 아들에게 더해 연습 웹 앱을 반나절에 만들 수 있는지 기획

랭킹 기능이 있다면 동기부여 오를 것이라고 생각해 firebase 로 은근하게 랭킹 만들었습니다만.

와이프 「상위진에 움직임이 없어서 시시하다」
와이「그럼, 데일리 랭킹 만들거야」

라고 하는 교환이 있어서.

그런 일도 있을까 하고 스코어 등록 일시의 타임 스탬프를 등록하고 있었기 때문에 쵸로 할 수 있을까 생각해 2개 대답을 하면, firestore 의 제한으로 빠졌습니다라는 이야기입니다.

데이터 구조


scores [
  {
    mode: 'ゲームモード', // 複数のゲームモードのスコアを同じテーブルに格納している
    name: 'ニックネーム',
    score: 得点
    createdAt: 登録日時のタイムスタンプ
  },
  ...
]

날짜 지정하지 않은 쿼리



query.js
const q = db.collection('scores')
            .where('mode', '==', this.displayGameMode) // 10秒モード, 30秒モード, 耐久モード
            .orderBy('score', this.orderBy) // 'desc' or 'asc'
            .limit(100)

여러 항목에 조건을 지정하는 경우 index를 만들어야 합니다.
게임 모드에 따라 점수 오름차순/점수 내림차순으로 값을 얻고 싶기 때문에 두 개의 index를 만듭니다.


  • mode Ascending, score Ascending
  • mode Ascending, score Descending

  • mode 는 [=] 의 비교로 밖에 사용하지 않기 때문에 오름차순이나 내림차순으로도 문제 없습니다.

    index 를 지정하지 않은 상태에서 query 를 던지면 브라우저의 콘솔에 경고가 나오고, 링크를 밟으면 위의 스크린샷의 페이지로 천이해 index 를 작성할 수 있으므로 여기는 고민하지 않고 이케합니다.

    일 지정하는 쿼리



    문제는 이쪽.
    그물을 세밀하게 검색하면 일을 지정할 수 있을 것 같고 실제로 지정할 수 있지만 다른 항목으로 정렬할 수 없다는 제한이 있습니다.

    query.js
    // 動く
    const q = db.collection('scores')
                .where('mode', '==', this.displayGameMode)
                .where('createdAt', '>=', startTime)
                .where('createdAt', '<', endTime)
                .limit(100)
    
    // 動く
    const q = db.collection('scores')
                .where('mode', '==', this.displayGameMode)
                .orderBy('createdAt', 'desc')
                .startAt(startTime) // startAt(>=), startAfter(>)
                .endBefore(endTime) // endAt(<), endBefore(<)
    
    // 動かない
    const q = db.collection('scores')
                .where('mode', '==', this.displayGameMode)
                .where('createdAt', '>=', startTime)
                .where('createdAt', '<', endTime)
                .orderBy('score', this.orderBy)  // ★範囲で取得する値と異なる項目でソートできない
                .limit(100)
    
    

    회피



    날짜에 붙여 등록도 취득도 실시하도록 하고, = 로 비교할 수 있도록 했습니다.

    query.js
    // 動く
    const q = db.collection('scores')
                .where('mode', '==', this.displayGameMode)
                .where('createdAt', '=', startTime)
                .orderBy('score', this.orderBy)
                .limit(100)
    

    결론



    개발 진행되고 나서 이런 것을 깨닫으면 치명상이거나 하기 때문에 조심해 주세요.

    좋은 웹페이지 즐겨찾기