首页 > 解决方案 > 在 Swift 中通过调用 firebase 云函数进行自动完成来获取结果的性能问题

问题描述

在我的 ElasticSearch 服务器中,我有一个tags这样的索引:

tags
    - tag_id_1
        - name: "Stack Overflow"
        - popularity: 100
    - tag_id_2
        - name: "Stack Exchange"
        - popularity: 80
    - tag_id_3
        - name: "Something else"
        - popularity: 20

每个标签都有一个namepopularity。例如,当用户在后端使用查询“Stack”进行搜索时,将执行 ElasticSearch,并返回所有包含“Stack”一词的标签并按其受欢迎程度按降序排序,然后显示在UITableView.

但是,我从这里了解到,我不应该向所有人开放我的 ElasticSearch 集群,相反,我应该创建自己的 REST API,从我的集群中获取结果并将结果返回。所以我做了。看下面的图片,它准确地显示了这一切在做什么:

在此处输入图像描述

但是,Firebase Cloud Function 似乎很慢。我希望在搜索文本更改后几乎立即显示结果。但通常结果会在 3 - 4 秒后返回。一个很好的例子是 GoogleMaps:当我使用 GoogleMaps 并搜索地址时,自动完成建议会很快返回并显示出来,就好像世界上所有的地址都存储在我的手机上一样。

我该如何做到这一点?我不应该将 Cloud Functions 用于此功能吗?

--------------------------更新1--------- ------------

看下面的 GIF,我通过调用 Firebase Cloud Function 来获取搜索结果,注意输入“S”后,几秒钟后,结果进来了:

在此处输入图像描述

云函数的代码是:

exports.searchTags = functions.https.onRequest((req, res) => {
    const { query } = req.query;

    const ESConfig = {
        uri: `https://<some_url>/tags/tag/_search`,
        method: 'GET',
        json: true,
        auth: // My ES authentication
        body: {
            query: {
                regexp: { name: `.*${query.toLowerCase()}.*` }
                // Use regex to match any tags that contains "query"
            },
            sort: [
                {
                    popularity: { order: 'desc' }
                    // Sort by popularity
                }
            ]
        }
    }

    // "request" is a node module called "request-promise"
    request(ESConfig).then((results) => {
        let tags = [];
        results.hits.hits.forEach((hit) => tags.push(hit["_source"].name))
        return res.status(200).send(tags)
    }).catch((error) => res.status(400).send(error))
})

但是,当我通过将设备直接连接到我的 ElasticSearch 集群来执行相同的 ElasticSearch 时,而不是调用云函数,搜索结果会在半秒内出现,这就是我想要的:

在此处输入图像描述

--------------------------更新 2--------- ------------

我按照@DougStevenson 的建议做了:

  1. 在我的应用程序startToSearch方法的开头,我创建了一个时间戳startTime = new Date()

  2. 在我的云函数开始时,我创建了一个时间戳requestReceivedTime = new Date()

  3. 在我的 Cloud Function 中,在 ElasticSearch 完成后返回结果之前,我创建了一个时间戳elasticSearchCompleteTime = new Date()

  4. 在我的应用程序中,当收到结果时,我创建了另一个时间戳getResultTime = new Date()

做了一些简单的数学运算后,我发现

  1. 连接到 Cloud Function(尚未执行)大约需要 2.5 秒,但有时只需 0.5 秒,它会有所不同:requestReceivedTime - startTime

  2. 弹性搜索仅需 0.1 - 0.2 秒:elasticSearchCompleteTime - requestReceivedTime

  3. 总时间通常为 3 秒:getResultTime - startTime

因此,我发现除了“连接到 Cloud Functions”需要 2.5 秒之外,其他每个步骤都需要很少的时间。我不知道为什么会发生这种情况,我有非常快的互联网。

标签: swiftperformancerestfirebaseelasticsearch

解决方案


推荐阅读