在firestore中的日期字段上查询不起作用 [英] query on date field in firestore not working

查看:60
本文介绍了在firestore中的日期字段上查询不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是编程的新手,只是一个爱好,通常,如果我有问题,我可以在互联网上的某个地方找到答案,但是花了2天的大部分时间,但仍然无法解决这个问题.我正在使用kotlin和android studio编写一个android应用程序.问的第一个问题,请保持温柔!

I'm new to programming and only as a hobby, usually if I have a problem I can find the answer on the internet somewhere, but having spent best part of 2 days and still can't figure this one out. I'm programming an android app using kotlin and android studio. First question asked, please be gentle!

我有一个保存在Firestore中的日期作为时间戳,并通过哈希映射与此代码一起保存了

I have a date saved in Firestore as timestamp saved with this code through hashmap

    val dateFormat = SimpleDateFormat("dd-MM-yyyy")
    val date = findViewById<TextView>(R.id.textMatchDate).text.toString()
    val timeStamp = Timestamp(dateFormat.parse(date)

然后

timeStamp 保存到Firestore.

timeStamp is then saved to firestore.

我要检索的代码是

        val date = "01-01-2020"
        val date1 = dateFormat.parse(date)
        val startDate = Timestamp(date1)

val db = FirebaseFirestore.getInstance()
        db.collection("snookerResults")
            .whereGreaterThan("date", startDate)
            .whereEqualTo("homeTeam", team)
            .get()
            .addOnSuccessListener {...}

为简单起见,我将0f表示为 startDate ,它是通过编程方式导出的,但格式相同. 尽管知道它们是应该返回的结果,但是我得到了一个空数组.如果我注释掉 whereGreaterThan 行,则会得到所有结果.

I've put the means 0f getting startDate for simplicity it is is derived programatically but is string of the same format. I get an empty array despite knowing ther are results that should be returned. If I comment out the whereGreaterThan line I get all results returned.

我有Log输出来说明正常运行时的问题,我得到以下输出:-

I have Log outputs to illustrate the problem when I run normally I get this output:-

2020-08-29 23:27:04.858 17112-17112/com.example.aggregatecalculator I/让分盘:所选球队为不伦瑞克

2020-08-29 23:27:05.086 17112-17112/com.example.aggregatecalculator I/障碍:startdate是Timestamp(seconds = 1577836800,nanoseconds = 0)

如果我注释掉 whereGreaterThan 行,那么我将得到此输出

If I comment out the whereGreaterThan line then I get this output

2020-08-29 23:37:08.331 18164-18164/com.example.aggregatecalculator I/让分盘:所选的球队是不伦瑞克省

2020-08-29 23:37:08.582 18164-18164/com.example.aggregatecalculator I/障碍:startdate是Timestamp(seconds = 1577836800,nanoseconds = 0)

2020-08-29 23:37:08.583 18164-18164/com.example.aggregatecalculator I/障碍:日期为[2020年1月1日星期三00:00:00 GMT + 00:00 2020,9月30日星期三00:00:00 GMT + 01:00 2020]

2020-08-29 23:37:08.793 18164-18164/com.example.aggregatecalculator I/handicapresults:日期为Timestamp(seconds = 1583712000,nanoseconds = 0)

2020-08-29 23:37:08.793 18164-18164/com.example.aggregatecalculator I/handicapresults:日期为时间戳(秒= 1575244800,纳秒= 0)

2020-08-29 23:37:08.793 18164-18164/com.example.aggregatecalculator I/handicapresults:日期为Timestamp(seconds = 1569798000,nanoseconds = 0)

2020-08-29 23:37:08.794 18164-18164/com.example.aggregatecalculator I/handicapresults:日期为Timestamp(seconds = 1572825600,nanoseconds = 0)

2020-08-29 23:37:08.794 18164-18164/com.example.aggregatecalculator I/handicapresults:日期为时间戳(秒= 1582502400,纳秒= 0)

2020-08-29 23:37:08.794 18164-18164/com.example.aggregatecalculator I/handicapresults:日期为Timestamp(seconds = 1584921600,nanoseconds = 0)

2020-08-29 23:37:08.795 18164-18164/com.example.aggregatecalculator I/handicapresults:日期为时间戳(秒= 1568588400,纳秒= 0)

2020-08-29 23:37:08.795 18164-18164/com.example.aggregatecalculator I/handicapresults:日期为Timestamp(seconds = 1574035200,nanoseconds = 0)

2020-08-29 23:37:08.795 18164-18164/com.example.aggregatecalculator I/handicapresults:日期为Timestamp(seconds = 1571612400,nanoseconds = 0)

2020-08-29 23:37:08.796 18164-18164/com.example.aggregatecalculator I/handicapresults:日期为Timestamp(seconds = 1571007600,nanoseconds = 0)

如您所见,时间戳是相同的格式,并且3个返回的时间戳大于startdate,因此在theary中应使用whereGreaterThan子句返回

As you can see timestamp is same format and 3 returned timestamp's are greater than the startdate so in theary should return with the whereGreaterThan clause

fun getNewHcap(team: String){
val players = arrayListOf<String>()
val db = FirebaseFirestore.getInstance()
db.collection("SnookerPlayers")
    .whereEqualTo("league", "Big Table Monday")
    .whereEqualTo("team", team)
    .get()
    .addOnSuccessListener { task ->
        for (doclist in task){
            val player = doclist["player"].toString()
            players.add(player)
        }
        val dates = hcapMinMaxDate()
        val dateFormat = SimpleDateFormat("dd-MM-yyyy")
        val date = "01-01-2020"
        val date1 = dateFormat.parse(date)
        val startDate = Timestamp(date1)
        val endDate = Timestamp(dates[1])
        Log.i("handicap", "startdate is $startDate")
       // Log.i("handicap", "startdate is $endDate")

        val db = FirebaseFirestore.getInstance()
        db.collection("snookerResults")
            //.whereGreaterThan("date", startDate)
            .whereEqualTo("homeTeam", team)

           //.whereLessThan("date", endDate)
            .get()
            .addOnSuccessListener { task ->
                for (docList in task){
                   // val player = docList["home player 1"].toString()
                    val date = docList["date"].toString()

                    Log.i("handicapresults", "date is $date")
                }
            }


        Log.i("handicap", "date is $dates")

    }
Log.i("handicap", "chosen team is $team")

推荐答案

尽管知道有应该返回的结果,但是我得到了一个空数组.如果我注释掉whereGreaterThan()行,则会得到所有结果.

I get an empty array despite knowing there are results that should be returned. If I comment out the whereGreaterThan() line I get all results returned.

由于以下代码行,您很可能会得到一个空数组:

You are getting an empty array most likely because of the following line of code:

db.collection("snookerResults")
    .whereGreaterThan("date", startDate)
    .whereEqualTo("homeTeam", team)
    .get()
    .addOnSuccessListener {...}

这是因为在同一查询中同时调用.whereGreaterThan().whereEqualTo()需要索引.可以在您的 Firebase控制台中手动创建该索引,或者如果您使用的是Android Studio,在日志猫中找到听起来像这样的消息:

And this is because calling .whereGreaterThan() along with .whereEqualTo() in the same query, require an index. This index can be created manually in your Firebase Console or if you are using Android Studio, you'll find in the logcat a message that sounds like this:

FAILED_PRECONDITION: The query requires an index. You can create it here: ...

您只需单击链接或将URL复制并粘贴到Web浏览器中,您的索引就会自动创建.等待几分钟,直到创建索引,您将获得所需的结果.

You can simply click on the link or copy and paste the URL into a web browser and your index will be created automatically. Wait a few minutes until the index is created and you'll get the desired results.

但是,这种方法可能不是最佳方法,因为您需要为数据库中的每个homeTeam创建一个索引.如果您有几个或固定数量的团队,这将起作用,但是如果您有很多团队,这将很困难,建议您重复数据.这种做法称为非规范化,这在Cloud Firestore中是很常见的做法.如果您是NoSQL数据库的新手,为了更好地理解,我建议您观看以下视频,去规范化Firebase数据库是正常的.适用于Firebase实时数据库,但相同的原理也适用于Cloud Firestore.除此之外,我想您可能还会对以下帖子中的回答感兴趣:

However, this approach might not be the best one, since you need to create an index for each homeTeam in your database. It will work if you have a few or a fixed number of teams but it will be hard if you have lots of them, case in which it's recommended to duplicate the data. This practice is called denormalization and it's quite common practice when it comes to Cloud Firestore. If you are new to the NoSQL database, for a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Database. It's for Firebase Realtime Database but the same principles apply to Cloud Firestore. Besides that, I think you might also be interested in my answer from the following post:

什么是Firebase Cloud Firestore中的非规范化?

因此,在您的特定情况下,我将创建一个新的收藏集,如下所示:

So in your particular case, I'd create a new collection that looks like this:

Firestore-root
  |
  --- homeSnookerResults (collection)
         |
         --- homeTeamId (document)
               |
               --- allResults (collection)
                     |
                     --- resultIdOne (document)
                           |
                           --- //result object properties

在这种情况下,看起来像这样的查询将达到目的:

In this case, a query that looks like this, will do the trick:

db.collection("homeSnookerResults")
    .document(homeTeamId)
    .collection("allResults")
    .whereGreaterThan("date", startDate)
    .get()
    .addOnSuccessListener {...}

在这种情况下,不需要索引.

Case in which, no index is required.

这篇关于在firestore中的日期字段上查询不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆