1

我需要在匹配給定的開始和結束日期,一個NDB queries獲取對象,但我不能做到這一點傳統的簡單查詢,因爲NDB抱怨:如何比較NDB查詢中的多個日期?

from google.appengine.ext import ndb 
from datetime import datetime 
from server.page.models import Post 

now = datetime.now() 
query = Post.query(
    Post.status == Post.STATUS_ACTIVE, 
    Post.date_published_start <= now, 
    Post.date_published_end >= now, 
) 
count = query.count() 

錯誤:

BadRequestError: Only one inequality filter per query is supported. 
Encountered both date_published_start and date_published_end 

有沒有這方面的解決方法?

+0

您可以隨時獲取滿足不等式查詢之一的實體並篩選Python中的其他不等式。 –

+0

@ JeffO'Neill我需要查詢,因爲我想對這些進行分頁,而不僅僅是獲取單個對象,並且遍歷數千個對象的效率非常低。 – rebelliard

回答

1

由於每個查詢限制的單個不等式過濾器的限制,動態獲取可直接用於分頁而無需進一步處理的單個結果列表是不可能的。相關GAE 4301 issue

正如傑夫所說,通過一個不等式(理想情況下最嚴格的一個)進行過濾,然後對結果進行進一步的動態處理始終是一種選擇,效率低下,但無法避免,如果您需要搜索的完全靈活性。

通過使用projection query可以提高性能 - 減少從數據存儲區傳輸到相關屬性的數據量。

你也可以嘗試執行2 keys-only queries,每個不等的一個,然後計算結果的交集 - 這可以更快地給出分頁計數和實體列表(作爲鍵)。最後,通過在頁面列表中按鍵的直接鍵查找,理想地批量處理(使用ndb.get_multi()),您將獲得當前頁面的實體。

根據您的預期用途,可能在某些情況下有其他選擇(當然需要額外的工作)。

您可以限制查詢的範圍。自從時間的開始,而不是查詢所有的實體,可能只是某些年份或月份的結果在某些情況下就足夠了。然後,您可以添加year和/或monthPost屬性,您可以在查詢中包含這些屬性作爲相等過濾器,從而可以減少從數千個動態處理到例如數百個或更少的結果數量。

對於典型的,經常使用的情況,您也可以完全避免查詢。例如,如果預期用途是生成幾種月度報告,那麼對於每種此類報告類型/月份,您可能會有一些Report實體包含Post密鑰的列表,只要Post實體的相關屬性發生更改,您就可以更新該實體。而不是查詢報告的Posts實體,而是使用相應Report實體的已有列表。您還可以在生成時存儲/緩存實際報告,以便直接重用(而不是在每次訪問時重新生成它)。

0

查詢多個篩選器和不等式的另一個解決方法是使用Search API。 https://cloud.google.com/appengine/training/fts_adv/lesson1#query_options

從文檔:

For example, the query job tag:"very important" sent < 2011-02-28 finds documents with the term job in any field, and also contain the phrase very important in a tag field, and a sent date prior to February 28, 2011.

只要把從數據存儲區查詢您的數據轉化爲搜索的文件並運行這些文件查詢。