社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  NoSql

为NoSQL和Flutter复制SQL联接的FireStore

Jake Anderson • 6 年前 • 1023 次点击  

我意识到,在复制与NoSQL文档数据库(如FireStore)的连接方面存在许多问题,但是我无法找到一个使用FireStore的dart/flutter的彻底解决方案。

我做过一些研究,我觉得在下面的例子中,我会寻找“多对多”的关系(如果这是错误的,请纠正我),因为将来可能需要查看所有的配置文件以及所有的连接。

在FireBase中,我有两个根级别的集合(配置文件和连接):

profile
    > documentKey(Auto Generated)
         > name = "John Smith"
         > uid = "xyc4567"

    > documentKey(Auto Generated)
         > name = "Jane Doe"
         > uid = "abc1234"

    > documentKey(Auto Generated)
         > name = "Kate Dee"
         > uid = "efg8910"



connection
    > documentKey(Auto Generated)
         > type = "friend"
         > profileuid = "abc1234"
         > uid = "xyc4567"

    > documentKey(Auto Generated)
         > type = "family"
         > profileuid = "abc1234"
         > uid = "efg8910"

在本例中,当用户john smith(uid:xyc4567)连接到Jane doe(uid:abc1234)和kate dee(uid:efg8910)时,已假设为该用户创建了“连接”文档。

下面是我要复制的关系SQL,以显示John Smith所连接的配置文件列表:

Select * FROM profile, connection 
WHERE profile.uid = connection.profileuid 
AND profile.uid = "xyc4567"

在flutter my flutter应用程序中,我有一个FireStore查询起点:

stream: Firestore.instance.collection('profile')
.where('uid', isEqualTo: "xyc4567").snapshots(),

显然,它只从一个集合返回。如何加入多对多关系中的集合?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/30507
 
1023 次点击  
文章 [ 2 ]  |  最新文章 6 年前
Jorge Vieira
Reply   •   1 楼
Jorge Vieira    6 年前

我这样做是为了连接两个colections对象和类别的结果。

我做了两个streambuilders来显示在一个列表中,在第一个列表中,我得到了类别并放入了一个地图,然后我查询了对象,并使用categoryID从地图中获得了类别对象:

StreamBuilder<QuerySnapshot>(
              stream: Firestore.instance
                  .collection('categoryPath')
                  .snapshots(),
              builder: (BuildContext context,
                  AsyncSnapshot<QuerySnapshot> categorySnapshot) {
                //get data from categories

                if (!categorySnapshot.hasData) {
                  return const Text('Loading...');
                }

                //put all categories in a map
                Map<String, Category> categories = Map();
                categorySnapshot.data.documents.forEach((c) {
                  categories[c.documentID] =
                      Category.fromJson(c.documentID, c.data);
                });

                //then from objects

                return StreamBuilder<QuerySnapshot>(
                  stream: Firestore.instance
                      .collection('objectsPath')
                      .where('day', isGreaterThanOrEqualTo: _initialDate)
                      .where('day', isLessThanOrEqualTo: _finalDate)
                      .snapshots(),
                  builder: (BuildContext context,
                      AsyncSnapshot<QuerySnapshot> objectsSnapshot) {
                    if (!objectsSnapshot.hasData)
                      return const Text('Loading...');

                    final int count =
                        objectsSnapshot.data.documents.length;
                    return Expanded(
                      child: Container(
                        child: Card(
                          elevation: 3,
                          child: ListView.builder(
                              padding: EdgeInsets.only(top: 0),
                              itemCount: count,
                              itemBuilder: (_, int index) {
                                final DocumentSnapshot document =
                                    objectsSnapshot.data.documents[index];
                                Object object = Object.fromJson(
                                    document.documentID, document.data);

                                return Column(
                                  children: <Widget>[
                                    Card(
                                      margin: EdgeInsets.only(
                                          left: 0, right: 0, bottom: 1),
                                      shape: RoundedRectangleBorder(
                                        borderRadius: BorderRadius.all(
                                            Radius.circular(0)),
                                      ),
                                      elevation: 1,
                                      child: ListTile(
                                        onTap: () {},
                                        title: Text(object.description,
                                            style: TextStyle(fontSize: 20)),
//here is the magic, i get the category name using the map 
of the categories and the category id from the object
                                        subtitle: Text(
                                          categories[object.categoryId] !=
                                                  null
                                              ? categories[
                                                      object.categoryId]
                                                  .name
                                              : 'Uncategorized',
                                          style: TextStyle(
                                              color: Theme.of(context)
                                                  .primaryColor),
                                        ),

                                      ),
                                    ),
                                  ],
                                );
                              }),
                        ),
                      ),
                    );

我不确定你是想要什么,还是很清楚,但我希望它能帮助你。

Alex Mamo
Reply   •   2 楼
Alex Mamo    6 年前

不幸的是,没有 JOIN 云FireStore或其他NoSQL数据库中的子句。在FireStore中,查询很浅。这意味着它们只从运行查询的集合中获取项。无法在单个查询中从两个顶级集合中获取文档。FireStore不支持一次性跨不同集合的查询。单个查询只能使用单个集合中文档的属性。

所以我能想到的最简单的解决方案是查询数据库以获取 uid 来自的用户 profile 收集。一旦您有了这个ID,就进行另一个数据库调用(在回调中),并从 connection 使用以下查询的集合:

stream: Firestore.instance.collection('connection').where('uid', isEqualTo: "xyc4567").snapshots(),

另一个解决方案是创建名为 连接 在每个用户下添加所有 连接 它下面的对象。这种做法被称为 denormalization 当涉及到火场时,这是一种常见的做法。如果你对noqsl数据库不熟悉,我建议你看这段视频, Denormalization is normal with the Firebase Database 为了更好的理解。它适用于FireBase实时数据库,但同样的规则也适用于云FireStore。

另外,当你复制数据时,有一件事需要记住。以同样的方式添加数据,您需要对其进行维护。换句话说,如果您想要更新/禁止一个项目,您需要在它存在的每一个地方进行更新/禁止。