我只想从Firestore集合中选择不是我写的文章。
真的那么难吗?

每篇文章都有“ owner_uid”字段。

就是这样:我只想写等效于"select * from articles where uid<>request.auth.uid"
TL; DR:已经找到解决方案:语言/平台的用法:https://firebase.google.com/docs/firestore/query-data/queries#kotlin+ktx_5

评论

Firestore现在支持“ where in”运算符。检查我的答案并更新接受的答案

#1 楼

2020年9月18日编辑
Firebase发行说明建议现在有not-in!=查询。 (现已提供适当的文档。)


not-in查找文档中指定字段的值不在指定数组中。

!=查找文档中指定字段的值不在指定数组中value不等于指定的值。

两个查询运算符都不会匹配不存在指定字段的文档。请确保查看所用语言语法的文档。
原始答案
Firestore不提供不相等检查。根据文档:

where()方法采用三个参数:要过滤的字段,比较操作和值。比较可以是<,<=,==,>或> =。

不等式运算不会像使用索引的其他运算那样扩展。 Firestore索引非常适合范围查询。使用这种类型的索引,对于不等式查询,后端仍然必须扫描集合中的每个文档才能得出结果,而当文档数量变大时,这对于性能而言是非常不利的。
您需要过滤结果以删除特定项目,但仍然可以在本地进行。
您还可以选择使用多个查询来排除不同的值。像这样,如果要除12外的所有内容,请查询值<12,然后查询值> 12,然后将结果合并到客户端中。

评论


但是在本地如何?如果馆藏“文章”中有1万篇文章被我阅读,则意味着我不得不疯狂地反复查询该馆藏,然后才能阅读未读的文章。

– android51130
17年11月12日19:30




例如,如何仅获取我已经不读的文章?
将readed_article_ids存储在我的用户Firestore文档中会扩大我的用户文档,并且每个firestore文档的限制都在1mb以内-某天readed_article_ids我的用户文档中的Firestore数组会超出此阈值。
如此困惑:(((

– android51130
17年11月12日在19:34

如此烦人的缺乏基本功能,令我感到遗憾的是,我选择Google Firebase作为BaaS

– Andrey Gordeev
17年11月22日在13:19



这里没有雷区。像任何nosql数据库一样,您必须学习如何以适合预期查询的方式对数据建模。

–道格·史蒂文森(Doug Stevenson)
17年11月23日在18:17

因此,我开发了一个用于创建文章的应用程序。当我没有找到关于如何显示其他用户创建的文章列表的任何解决方案时,我感到很惊讶。在数百万(仅一个!)文章的情况下,本地过滤是胡扯。 ^(

– android51130
17年11月28日在19:29



#2 楼

对于android,使用Task Api即可轻松实现。
新手示例:

    FirebaseFirestore db = FirebaseFirestore.getInstance();
    Query lessQuery = db.collection("users").whereLessThan("uid", currentUid);
    Query greaterQuery = db.collection("users").whereGreaterThan("uid", currentUid);
    Task lessQuery Task = firstQuery.get();
    Task greaterQuery = secondQuery.get();

    Task combinedTask = Tasks.whenAllSuccess(lessQuery , greaterQuery)
                             .addOnSuccessListener(new OnSuccessListener<List<Object>>() {
        @Override
        public void onSuccess(List<Object> list) {

            //This is the list of "users" collection without user with currentUid
        }
    });


此外,您还可以结合使用任何查询集。

对于Web来说,存在rxfire

评论


这是最佳做法吗?如果我正在使用firebase-ui的Firestore分页适配器,还有哪些其他解决方案?

– Sabeeh Ul Haq
3月18日8:54

#3 楼

这是我如何使用JavaScript解决问题的示例:

let articlesToDisplay = await db
  .collection('articles')
  .get()
  .then((snapshot) => {
    let notMyArticles = snapshot.docs.filter( (article) => 
      article.data().owner_uid !== request.auth.uid
    )
    return notMyArticles
  })


它获取所有文档,并使用Array.prototype.filter()过滤掉您不知道的文档不想。它可以在服务器端或客户端运行。

评论


您是否在Firebase控制台中计算了从数据库读取的数据?我认为通过这种方式,您始终会读取所有“ atricles”数据库图,然后才对项目进行过滤-如果图形很大,则服务器内存和CPU的使用量将非常昂贵

– android51130
3月1日12:10

是的,如上所述,此解决方案可读取馆藏中的所有文档。不适合大型收藏。您可以按日期过滤以获取例如上周的文章,只是为了减小篇幅,但取决于用例。

–达伦·G(Darren G)
3月2日,19:24

#4 楼

更新Darren G的答案,这导致“ TypeError:将圆形结构转换为JSON”。当我们执行过滤操作时,整个firebase对象被添加回数组,而不仅仅是数据。我们可以通过将filter方法与map方法链接在一起来解决此问题。
 let articles = []
let articlesRefs = await db.collection('articles').get();

articles = articlesRefs.docs
           .filter((article) => article.data.uid !== request.auth.uid) //Get Filtered Docs
           .map((article) => article.data()); //Process Docs to Data

return articles

 

仅供参考:这是一项昂贵的操作,因为您将从数据库中获取所有文章,然后进行本地过滤。

#5 楼



在一个(或两个)文档中跟踪所有用户ID。


过滤掉不需要的ID,


使用“在哪里“



var mylistofidwherenotme =  // code to fetch the single document where you tracked all user id, then filter yourself out


database.collection("articles").where("blogId", "in", mylistofidwherenotme)



评论


您不能从文档中过滤掉不需要的ID,也不能每次都获取所有ID以便在本地进行过滤-我们所说的是庞大的数据库

– android51130
9月16日下午17:16

#6 楼

let query = docRef.where('role','>',user_role).where('role','<',user_role).get()


在带字符串值的Firestore中,此功能不可用作“不相等”操作

评论


我不认为链接.where会像OR逻辑一样工作,应该是AND逻辑。所以这可能行不通吗?

–洪浩C
19-09-23在8:49

您必须分别查询两个条件和合并结果,从而增加读取操作的次数并从口袋里掏钱

–阴影
1月26日18:52

将返回一个空列表

–托尼·奥哈根(Tony O'Hagan)
6月15日12:30

#7 楼

您可以在javascript代码中过滤对象数组。

var data=[Object,Object,Object] // this is your object array
var newArray = data.filter(function(el) {
   return el.gender != 'Male';
});