使用多个字段上的不等式查询 Firebase

huangapple go评论75阅读模式
英文:

Querying Firebase with Inequalities on Multiple Fields

问题

const Fiis = async () => {
    const data: any[] = [];

    // 在 Firebase 上执行具有不同字段的不等式查询。
    // 目标:获取股息收益率在8到20之间且市净率小于或等于1的文档。
    // 问题:当前查询会引发错误“FirebaseError: 无效查询。所有带有不等式(<、<=、!=、not-in、> 或 >=)的筛选器必须在同一字段上。但你在 'dividendYield' 和 'pvp' 上都有不等式筛选器。”

    const q = query(
        collection(db, "fiis"),
        where("dividendYield", ">=", 8),
        where("dividendYield", "<=", 20),
        // 下面的代码被注释掉,因为使用它会导致上述错误。
        // where("pvp", "<=", 1),
    );

    const querySnapshot = await getDocs(q);

    querySnapshot.forEach((doc) => {
        // 对于查询文档快照,doc.data() 永远不会是 undefined
        console.log(doc.id, " => ", doc.data());
        data.push(doc.data());
    });

    return (
        <div>
            <Modal />
            <span>{data.length}</span>
            {data.length > 0 && <MyTable data={data} />}
        </div>
    );
};

export default Fiis;
英文:
const Fiis = async () =&gt; {
    const data: any[] = [];

    // Performing a query with inequalities on different fields in Firebase.
    // Goal: Get documents with dividendYield between 8 and 20 and pvp less than or equal to 1.
    // Problem: The current query throws the error &quot;FirebaseError: Invalid query. All where filters with an inequality (&lt;, &lt;=, !=, not-in, &gt;, or &gt;=) must be on the same field. But you have inequality filters on &#39;dividendYield&#39; and &#39;pvp&#39;.&quot;

    const q = query(
        collection(db, &quot;fiis&quot;),
        where(&quot;dividendYield&quot;, &quot;&gt;=&quot;, 8),
        where(&quot;dividendYield&quot;, &quot;&lt;=&quot;, 20),
        // The code below is commented out because using it results in the error mentioned above.
        // where(&quot;pvp&quot;, &quot;&lt;=&quot;, 1),
    );

    const querySnapshot = await getDocs(q);

    querySnapshot.forEach((doc) =&gt; {
        // doc.data() is never undefined for query doc snapshots
        console.log(doc.id, &quot; =&gt; &quot;, doc.data());
        data.push(doc.data());
    });

    return (
        &lt;div&gt;
            &lt;Modal /&gt;
            &lt;span&gt;{data.length}&lt;/span&gt;
            {data.length &gt; 0 &amp;&amp; &lt;MyTable data={data} /&gt;}
        &lt;/div&gt;
    );
};

export default Fiis;

I'm using Next.js with the latest version that allows async functions, and I'm trying to perform a query on Firebase. I need to retrieve documents with the "dividendYield" field having values between 8 and 20 and, at the same time, the "pvp" field with a value less than or equal to 1.

However, when I add the second condition in the code (as shown in the code above), I receive the following error:

> FirebaseError: Invalid query. All where filters with an inequality (<, <=, !=, not-in, >, or >=) must be on the same field. But you have inequality filters on 'dividendYield' and 'pvp'.

How can I perform this query using inequalities on different fields in the same code?

答案1

得分: 2

根据错误消息和Firestore的查询限制文档中所述:

在复合查询中,范围(<,<=,>,>=)和不等于(!=,not-in)比较必须都在同一字段上进行筛选。

因此,您不能在Firestore查询中对两个条件执行范围或不等于筛选。

两种解决方法:

  • 在查询中执行一个相等条件,并在应用程序代码中执行其余筛选。这意味着您将读取比所需更多的数据,因此您将希望在调用数据库时使用过滤器,以排除大部分数据。
  • 添加一个包含两个值串联的单个字段,然后对该字段执行不等于筛选。这在使用NoSQL数据库时非常常见,通常我们会根据应用程序的用例更改/增强数据模型。在这种情况下,权衡是增加文档大小和相关成本,但不再需要从数据库中读取太多文档。
英文:

As the error message says and as is also mentioned in the documentation on Firestore's query limitations:

> In a compound query, range (<, <=, >, >=) and not equals (!=, not-in) comparisons must all filter on the same field.

So you can't perform a range or inequality filter on two conditions in a query to Firestore.

Two workarounds:

  • Perform one equality in the query, and perform the rest of the filtering in your application code. This means you'll be reading more data than needed, so you'll want to use the filter that disqualifies most of the data in the call to the database.
  • Add a single field with the two values concatenated, and then perform an inequality on that. This is actually quite common when working with NoSQL databases, where we often change/augment our data model for the use-cases of our app. Here the trade-off becomes that you increase your document size and associated cost, but don't hav to read too many documents from the database anymore.

huangapple
  • 本文由 发表于 2023年7月17日 21:50:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76705127.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定