Firebase Firestore查询子集合

Firebase Firestore查询子集合,firebase,google-cloud-firestore,Firebase,Google Cloud Firestore,我想我读过,您可以使用新的Firebase Firestore查询子集合,但我没有看到任何示例。例如,我的Firestore设置如下所示: 舞蹈[收藏] 丹塞纳 歌曲[精选] 歌曲名 我如何查询“查找songName='X'的所有舞蹈”更新2019-05-07 今天我们发布了,这些允许您跨子集合进行查询 例如,在web SDK中: db.collectionGroup('Songs') .where('songName', '==', 'X') .get() 这将匹配集合路

我想我读过,您可以使用新的Firebase Firestore查询子集合,但我没有看到任何示例。例如,我的Firestore设置如下所示:

  • 舞蹈[收藏]
    • 丹塞纳
    • 歌曲[精选]
      • 歌曲名

我如何查询“查找songName='X'的所有舞蹈”

更新2019-05-07

今天我们发布了,这些允许您跨子集合进行查询

例如,在web SDK中:

db.collectionGroup('Songs')
  .where('songName', '==', 'X')
  .get()
这将匹配集合路径最后一部分为“歌曲”的任何集合中的文档

您最初的问题是关于查找songName='X'的舞蹈,但这仍然无法直接实现,但是,对于匹配的每首歌曲,您可以加载其父歌曲

原始答案

这是一项尚不存在的功能。它被称为“集合组查询”,允许您查询所有歌曲,而不管哪个舞蹈包含它们。这是我们打算支持的东西,但没有具体的时间表来说明它何时到来

此时的另一种结构是使歌曲成为顶级收藏,并使歌曲的舞蹈成为歌曲属性的一部分。

更新 现在Firestore支持数组包含

有这些文件吗

    {danceName: 'Danca name 1', songName: ['Title1','Title2']}
    {danceName: 'Danca name 2', songName: ['Title3']}
这样做

collection("Dances")
    .where("songName", "array-contains", "Title1")
    .get()...

@Nelson.b.austin由于firestore还没有,我建议您采用平面结构,即:

Dances = {
    danceName: 'Dance name 1',
    songName_Title1: true,
    songName_Title2: true,
    songName_Title3: false
}
通过这种方式,您可以完成:

var songTitle = 'Title1';
var dances = db.collection("Dances");
var query = dances.where("songName_"+songTitle, "==", true);

我希望这会有所帮助。

如果将歌曲存储为对象而不是集合,会怎么样?每个舞蹈作为,歌曲作为字段:键入对象(不是集合)

然后,您可以查询与aNameOfASong的所有舞蹈:

db.collection('Dances'))
.where('songs.aNameOfASong','=',true)
.get()
.then(函数(querySnapshot){
querySnapshot.forEach(函数(doc){
console.log(doc.id,=>,doc.data());
});
})
.catch(函数(错误){
log(“获取文档时出错:”,错误);
});

最好使用平面数据结构。
这些文档详细说明了不同数据结构的优缺点

特别是关于具有子集合的结构的限制:

您不能轻松删除子集合,也不能跨子集合执行复合查询

与扁平数据结构的据称优势相比:

根级集合提供了最大的灵活性和可伸缩性,以及每个集合内的强大查询


您始终可以这样搜索:-

this.key$=newbehaviorsubject(null);
返回此.key$.switchMap(key=>
这是火炉店
.collection(“dances”).doc(“danceName”).collection(“歌曲”,ref=>
裁判
.其中(“songName”,“==”,X)
)
.snapshotChanges()
.map(操作=>{
if(actions.toString()){
返回actions.map(a=>{
const data=a.payload.doc.data(),如图所示;
const id=a.payload.doc.id;
返回{id,…data};
});
}否则{
返回false;
}
})
);

2019年更新

Firestore已发布收集组查询。见上面吉尔的回答或官方的回答


先前的答案

正如Gil Gilbert所说,似乎集合组查询目前正在进行中。同时,最好使用根级别的集合,并使用文档UID链接这些集合

对于那些还不知道的人,Jeff Delaney为任何在Firebase(和Angular)上工作的人提供了一些难以置信的指南和资源

-在这里,他详细介绍了NoSQL和Firestore DB的基本结构

-这些都是更先进的技术,让您牢记在心。对于那些想要将Firestore技能提升到新水平的人来说,这是一本很棒的读物

var songs = []    
db.collection('Dances')
      .where('songs.aNameOfASong', '==', true)
      .get()
      .then(function(querySnapshot) {
        var songLength = querySnapshot.size
        var i=0;
        querySnapshot.forEach(function(doc) {
           songs.push(doc.data())
           i ++;
           if(songLength===i){
                console.log(songs
           }
          console.log(doc.id, " => ", doc.data());
        });
       })
       .catch(function(error) {
         console.log("Error getting documents: ", error);
        });
查询限制

Cloud Firestore不支持以下类型的查询:

  • 在不同字段上使用范围筛选器的查询

  • 跨多个集合或子集合的单个查询。每个查询针对单个文档集合运行。更多 有关数据结构如何影响查询的信息,请参阅

  • 逻辑或查询。在这种情况下,您应该为每个OR条件创建一个单独的查询,并在应用程序中合并查询结果

  • 使用条款在这种情况下,应该将查询拆分为大于查询和小于查询。例如,尽管 不支持查询子句where(“age”、“!=”、“30”),您可以 通过组合两个查询获得相同的结果集,一个查询带有子句 其中(“年龄”,30岁)


  • 2019年7月8日的最新更新:

    db.collectionGroup('Songs')
      .where('songName', isEqualTo:'X')
      .get()
    
    我找到了解决办法。 请检查这个

    var museums = Firestore.instance.collectionGroup('Songs').where('songName', isEqualTo: "X");
            museums.getDocuments().then((querySnapshot) {
                setState(() {
                  songCounts= querySnapshot.documents.length.toString();
                });
            });
    
    然后,您可以从console.firebase.google.com查看云firestore中的数据、规则、索引和用法选项卡。 最后,您应该在indexes选项卡中设置索引

    在此处填写集合ID和一些字段值。 然后选择集合组选项。
    好好享受吧。谢谢

    我正在使用可观测数据和包装器,但下面是我如何做到这一点的

    这有点疯狂,我仍然在学习可观测的东西,我可能做得太过分了。但这是一个很好的练习

    一些解释(不是RxJS专家):

    • songId$是一个可观察的,将发出ID
    • dance$是一个可观察对象,它读取该id,然后只获取第一个值
    • 然后,它查询所有歌曲的collectionGroup以查找其所有实例
    • 基于它遍历到父舞蹈的实例并获取它们的ID
    • 现在我们有了所有的舞蹈ID,我们需要查询它们以获取它们的数据。但是
      var museums = Firestore.instance.collectionGroup('Songs').where('songName', isEqualTo: "X");
              museums.getDocuments().then((querySnapshot) {
                  setState(() {
                    songCounts= querySnapshot.documents.length.toString();
                  });
              });