同様の配列を持つFirestoreクエリドキュメント(Node.js / Admin SDK)

Aug 16 2020

あなたがこの配列を持っていると想像してください

[10.3, 14, 12.4, 3.5]

また、DBには、これらの配列を含む2つのドキュメントがあります。

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

ここで、同じ2つの配列(それぞれを交互に)を持つ+1000000ドキュメントがあると想像してください...現在の配列と同様の値を持つすべてのドキュメントを取得する方法はありますか?

つまり、次のようなものです。

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

配列を持つすべてのドキュメントを取得するために:

[10, 13.1, 0, -10]

または、唯一の方法は、すべてのドキュメントをダウンロードすることです。これは非常に時間がかかる可能性があり、次に最も類似したドキュメントを繰り返し検索しますか?「似たようなポイントの位置」、「ユーザーが似たような体重を失った週」などについて話すとき、これは本当に興味深いと思います...

ありがとう。

回答

3 JayCodist Aug 16 2020 at 09:20

現時点では、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()比較の許容範囲を増減するために、渡される引数を変更することもできます。