国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

獲取集合中隨機文檔的Firestore方法
P粉277305212
P粉277305212 2023-10-19 11:39:22
0
2
1340

對于我的應(yīng)用程序來說,能夠從 Firebase 的集合中隨機選擇多個文檔至關(guān)重要。

由于 Firebase 中沒有內(nèi)置的本機函數(shù)(據(jù)我所知)來實現(xiàn)執(zhí)行此操作的查詢,因此我的第一個想法是使用查詢游標(biāo)來選擇隨機的開始和結(jié)束索引,前提是我有數(shù)字集合中的文檔數(shù)量。

這種方法可以工作,但只能以有限的方式工作,因為每個文檔每次都會與其相鄰文檔按順序提供;但是,如果我能夠通過其父集合中的索引選擇文檔,我可以實現(xiàn)隨機文檔查詢,但問題是我找不到任何文檔來描述如何執(zhí)行此操作,或者即使可以執(zhí)行此操作。

這是我想要做的事情,請考慮以下 firestore 架構(gòu):

root/
  posts/
     docA
     docB
     docC
     docD

然后在我的客戶端(我在 Swift 環(huán)境中)我想編寫一個可以執(zhí)行此操作的查詢:

db.collection("posts")[0, 1, 3] // would return: docA, docB, docD

我可以做一些類似的事情嗎?或者,是否有其他方法可以以類似的方式選擇隨機文檔?

請幫忙。

P粉277305212
P粉277305212

全部回復(fù)(2)
P粉668113768

發(fā)布此內(nèi)容是為了幫助將來遇到此問題的任何人。

如果您使用自動 ID,則可以生成新的自動 ID 并查詢最接近的自動 ID,如Dan McGrath 的回答.

我最近創(chuàng)建了一個隨機報價 api,需要從 firestore 集合中獲取隨機報價。
這就是我解決這個問題的方法:

var db = admin.firestore();
var quotes = db.collection("quotes");

var key = quotes.doc().id;

quotes.where(admin.firestore.FieldPath.documentId(), '>=', key).limit(1).get()
.then(snapshot => {
    if(snapshot.size > 0) {
        snapshot.forEach(doc => {
            console.log(doc.id, '=>', doc.data());
        });
    }
    else {
        var quote = quotes.where(admin.firestore.FieldPath.documentId(), '<', key).limit(1).get()
        .then(snapshot => {
            snapshot.forEach(doc => {
                console.log(doc.id, '=>', doc.data());
            });
        })
        .catch(err => {
            console.log('Error getting documents', err);
        });
    }
})
.catch(err => {
    console.log('Error getting documents', err);
});

查詢的關(guān)鍵是這樣的:

.where(admin.firestore.FieldPath.documentId(), '>', key)

如果沒有找到文檔,則以相反的操作再次調(diào)用。

希望這會有所幫助!

P粉985686557

使用隨機生成的索引和簡單查詢,您可以從 Cloud Firestore 中的集合或集合組中隨機選擇文檔。

這個答案分為 4 個部分,每個部分都有不同的選項:

  1. 如何生成隨機索引
  2. 如何查詢隨機索引
  3. 選擇多個隨機文檔
  4. 重新播種以獲得持續(xù)的隨機性

如何生成隨機索引

這個答案的基礎(chǔ)是創(chuàng)建一個索引字段,當(dāng)按升序或降序排序時,會導(dǎo)致所有文檔隨機排序。有多種不同的方法來創(chuàng)建它,所以讓我們看一下 2,從最容易獲得的方法開始。

自動識別版本

如果您使用我們的客戶端庫中提供的隨機生成的自動 ID,您可以使用同一系統(tǒng)隨機選擇文檔。在這種情況下,隨機排序的索引文檔ID。

稍后在我們的查詢部分中,您生成的隨機值是一個新的自動 ID (iOS,AndroidWeb),您查詢的字段是 __name__ 字段,并且 '后面提到的“l(fā)ow value”就是一個空字符串。這是迄今為止生成隨機索引的最簡單方法,并且無論語言和平臺如何,都可以工作。

默認(rèn)情況下,文檔名稱 (__name__) 僅按升序索引,并且除了刪除和重新創(chuàng)建之外,您也無法重命名現(xiàn)有文檔。如果您需要其中任何一個,您仍然可以使用此方法,只需將自動 ID 存儲為名為 random 的實際字段,而不是為此目的重載文檔名稱。

隨機整數(shù)版本

當(dāng)你編寫文檔時,首先生成一個有界范圍內(nèi)的隨機整數(shù),并將其設(shè)置為一個名為random的字段。根據(jù)您期望的文檔數(shù)量,您可以使用不同的有界范圍來節(jié)省空間或降低沖突風(fēng)險(這會降低此技術(shù)的有效性)。

您應(yīng)該考慮您需要哪種語言,因為會有不同的考慮因素。雖然 Swift 很簡單,但 JavaScript 卻有一個值得注意的問題:

  • 32 位整數(shù):非常適合小型 (~10K 不太可能發(fā)生沖突)數(shù)據(jù)集
  • 64 位整數(shù):大型數(shù)據(jù)集(注意:JavaScript 本身不支持,

這將創(chuàng)建一個索引,其中的文檔隨機排序。稍后在我們的查詢部分中,您生成的隨機值將是這些值中的另一個,而后面提到的“低值”將是 -1。

如何查詢隨機索引

現(xiàn)在您已經(jīng)有了一個隨機索引,您將需要查詢它。下面我們看一些選擇 1 個隨機文檔的簡單變體,以及選擇多個 1 個文檔的選項。

對于所有這些選項,您需要生成一個新的隨機值,其形式與您在編寫文檔時創(chuàng)建的索引值相同,由下面的變量 random 表示。我們將使用該值在索引上查找隨機點。

環(huán)繞式

現(xiàn)在您有了隨機值,您可以查詢單個文檔:

let postsRef = db.collection("posts")
queryRef = postsRef.whereField("random", isGreaterThanOrEqualTo: random)
                   .order(by: "random")
                   .limit(to: 1)

檢查是否已返回文檔。如果沒有,請再次查詢,但使用隨機索引的“低值”。例如,如果您執(zhí)行隨機整數(shù),則 lowValue0

let postsRef = db.collection("posts")
queryRef = postsRef.whereField("random", isGreaterThanOrEqualTo: lowValue)
                   .order(by: "random")
                   .limit(to: 1)

只要您有一個文檔,就保證您至少返回 1 個文檔。

雙向

環(huán)繞方法實現(xiàn)起來很簡單,并且允許您在僅啟用升序索引的情況下優(yōu)化存儲。缺點之一是價值觀可能受到不公平的保護(hù)。例如,如果 10K 中的前 3 個文檔(A、B、C)具有隨機索引值 A:409496、B:436496、C:818992,則 A 和 C 被選擇的機會小于 1/10K,而B 因 A 的接近而被有效屏蔽,并且只有大約 1/160K 的機會。

您可以在 >= 之間隨機選擇,而不是單向查詢并在未找到值時回繞,這會降低概率不公平屏蔽的值減半,代價是索引存儲加倍。

如果一個方向沒有返回結(jié)果,則切換到另一個方向:

queryRef = postsRef.whereField("random", isLessThanOrEqualTo: random)
                   .order(by: "random", descending: true)
                   .limit(to: 1)

queryRef = postsRef.whereField("random", isGreaterThanOrEqualTo: random)
                   .order(by: "random")
                   .limit(to: 1)

選擇多個隨機文檔

通常,您需要一次選擇多個隨機文檔。根據(jù)您想要的權(quán)衡,有兩種不同的方法可以調(diào)整上述技術(shù)。

沖洗并重復(fù)

這個方法很簡單。只需重復(fù)該過程,包括每次選擇一個新的隨機整數(shù)。

此方法將為您提供隨機的文檔序列,而不必?fù)?dān)心重復(fù)看到相同的模式。

代價是它會比下一個方法慢,因為它需要為每個文檔單獨往返服務(wù)。

繼續(xù)保持

在此方法中,只需增加所需文檔的限制數(shù)量即可。這有點復(fù)雜,因為您可能會在調(diào)用中返回 0..limit 文檔。然后,您需要以相同的方式獲取丟失的文檔,但限制減少到僅存在差異。如果您知道文檔總數(shù)比您要求的數(shù)量多,則可以通過忽略在第二次調(diào)用(但不是第一次)時永遠(yuǎn)無法取回足夠文檔的邊緣情況來進(jìn)行優(yōu)化。

此解決方案的權(quán)衡是重復(fù)序列。雖然文檔是隨機排序的,但如果最終出現(xiàn)重疊范圍,您將看到與之前看到的相同模式。有一些方法可以減輕這種擔(dān)憂,我們將在下一節(jié)有關(guān)重新播種的內(nèi)容中討論。

此方法比“沖洗并重復(fù)”更快,因為您將在最好情況下一次調(diào)用或最壞情況下兩次調(diào)用中請求所有文檔。

重新播種以獲得持續(xù)的隨機性

雖然如果文檔集是靜態(tài)的,則此方法會隨機為您提供文檔,但返回每個文檔的概率也將是靜態(tài)的。這是一個問題,因為根據(jù)它們獲得的初始隨機值,某些值可能具有不公平的低或高概率。在許多用例中,這很好,但在某些用例中,您可能希望增加長期隨機性,以便有更均勻的機會返回任何 1 個文檔。

請注意,插入的文檔最終會交織在中間,逐漸改變概率,刪除文檔也是如此。如果給定文檔數(shù)量,插入/刪除率太小,有一些策略可以解決這個問題。

多隨機

您不必?fù)?dān)心重新播種,您始終可以為每個文檔創(chuàng)建多個隨機索引,然后每次隨機選擇其中一個索引。例如,讓字段 random 成為包含子字段 1 到 3 的映射:

{'random': {'1': 32456, '2':3904515723, '3': 766958445}}

現(xiàn)在您將隨機查詢 random.1、random.2、random.3,從而創(chuàng)建更大的隨機性分布。這本質(zhì)上是用增加的存儲空間來節(jié)省因重新播種而增加的計算(文檔寫入)。

寫入時重新設(shè)定種子

每次更新文檔時,都會重新生成random 字段的隨機值。這將在隨機索引中移動文檔。

讀取時重新播種

如果生成的隨機值不是均勻分布的(它們是隨機的,因此這是預(yù)期的),則可能會在不適當(dāng)?shù)臅r間內(nèi)選擇同一文檔。通過在讀取隨機選擇的文檔后使用新的隨機值更新該文檔,可以輕松解決此問題。

由于寫入成本更高并且可能成為熱點,因此您可以選擇僅在讀取時間的子集時進(jìn)行更新(例如,if random(0,100) === 0) update;)。

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板