首页 > 解决方案 > 合并 2 查询并删除重复的 Firestore

问题描述

我写了 2 个查询:

Stream<QuerySnapshot> users = usersRef
    .where("displayNameSearch", arrayContains: query.toLowerCase())
    .snapshots();

Stream<QuerySnapshot> users2 = usersRef
    .where("usernameSearch", arrayContains: query.toLowerCase())
    .snapshots();

setState(() {
  searchResultsDisplayName = users;
  searchResultsUsername = users2;
});

但是两者都可以返回相同的文档,所以我想知道是否有办法以不重复的方式合并两个结果?

更新

在弗兰克的回答之后,我试着这样做:

return StreamBuilder(
      stream: searchResultsDisplayName,
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return circularProgress();
        }
        return StreamBuilder(
            stream: searchResultsUsername,
            builder: (context, snapshot2) {
              if (!snapshot2.hasData) {
                return circularProgress();
              }
              List<UserResult> searchResults = [];
              snapshot.data.documents.forEach((doc) {
                User user = User.fromDocument(doc);
                UserResult searchResult = UserResult(user);
                searchResults.add(searchResult);
              });
              snapshot.data.documents.forEach((doc) {
                snapshot2.data.documents.forEach((doc2) {
                  if (doc2['id'] != doc['id']) {
                    User user = User.fromDocument(doc2);
                    UserResult searchResult = UserResult(user);
                    searchResults.add(searchResult);
                  }
                });
              });

这是正确的方法吗?

标签: flutterdartgoogle-cloud-firestore

解决方案


没有一种简单、可扩展的方法可以将一个查询的结果从另一个查询中排除。但是您应该能够通过将每个文档的documentId字段相互比较来合并结果客户端。

如果您在完成这项工作时遇到困难,请发布您尝试过的内容,以便我们发现您犯了错误的地方。


更新:在您的代码中,您现在执行以下操作:

snapshot.data.documents.forEach((doc) {
  snapshot2.data.documents.forEach((doc2) {
    if (doc2['id'] != doc['id']) {
      User user = User.fromDocument(doc2);
      UserResult searchResult = UserResult(user);
      searchResults.add(searchResult);
    }
  });
});

只要任一快照有多个结果,此代码就不起作用。我强烈建议在调试器中单步执行此代码,以便您了解它为什么不起作用。

您更有可能寻找这样的东西(它可能包含语法错误,因为我实际上并没有运行它):

var merged = new List<DocumentSnapshot>();
snapshot.data.documents.forEach((doc) {
  merged.add(doc);
});
snapshot2.data.documents.forEach((doc2) {
  if (!merged.indexWhere((doc) => (doc2['id'] != doc['id']) >= 0) {
    merged.add(doc2);
  }
});

推荐阅读