【问题标题】:Firestore Query Documents With Similar Array (Node.js/Admin SDK)Firestore 查询具有相似数组的文档(Node.js/Admin SDK)
【发布时间】:2020-12-05 11:52:38
【问题描述】:

假设你有这个数组

[10.3, 14, 12.4, 3.5]

在您的数据库中,您还有两个包含这些数组的文档:

First document -> [10, 13.1, 0, -10]
Second document -> [0, 0, 0, 0]

现在假设您有 +1000000 个具有相同两个数组的文档(在每个数组之间交替)...有没有办法获取与当前数组具有相似值的所有文档?

我的意思是,像这样:

   ...
   .where("array", "isSimilar", yourArray)
   .get()

这样我就得到了所有包含数组的文档:

[10, 13.1, 0, -10]

或者唯一的方法是下载每一个文档,可能真的很慢,然后迭代和搜索最相似的?我认为在谈论“相似点位置”、“用户减重相似的周数”时,这真的很有趣……

谢谢。

【问题讨论】:

    标签: javascript firebase google-cloud-platform google-cloud-firestore


    【解决方案1】:

    目前,firestore 不支持这种查询。因此,我建议您更新结构以包含用于数组比较的字符串字段。所以每个文档看起来像这样:

    {
       array: [12, 11, 8, 9],
       arrayStr: "12,11,8,9",
       ...
    }
    

    您只需对所有现有文档调用doc.array.join(",") 并将值保存到文档中即可实现此结构。

    然后,就可以与 firestore 查询进行比较,如下所示:

    const arrToCompare = [12, 11, 8, 9];
    const snapshot = await firestore().collection(collection).where("arrayStr", "==", arrToCompare.join(",")).get();
    ...
    

    更新:要通过相似性而不是相等性进行比较,一种可能的方法是在创建期间将“相似性”逻辑应用于 arrayStr 字段。例如,如果您希望允许小于 0.5 的差异,则可以在保存为字符串之前对数组元素使用 Math.round()。像这样:

    const array = [12.2, 10.7, 8.111, 9.0];
    const arrayStr = array.map(num => Math.round(num)).join(","); //"12,11,8,9"
    

    然后你会这样查询:

    const arrToCompare = [12, 11, 8, 9];
    const snapshot = await firestore().collection(collection).where("arrayStr", "==", arrToCompare.map(num => Math.round(num)).join(",")).get();
    // Results would include arrays like [12.2, 10.7, 8.111, 9.0]
    ...
    

    当然,您可以更改传递给 Math.round() 的参数,以增加或减少比较的容忍度

    【讨论】:

    • 这看起来真的很有用。谢谢你。但是,可以比较这些项目吗?我的意思是,我想要类似的数组(例如,每个数字项可以有一个 epsilon 的边距)
    • 您的意思是比较应该容​​忍小的差异吗?因此,比较相似性而不是相等性?像“2.118”匹配“2.1”吗?
    • 是的,正是这个。
    • 我也需要相似性,而不是相等性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 2021-09-30
    • 1970-01-01
    • 2021-10-22
    • 2018-05-24
    相关资源
    最近更新 更多