2011-09-07 33 views
2

數據建模我作爲字符串類型的地址的列表,我想找到其位置值列表中的內容匹配的所有事件。因爲我有成千上萬的這樣的條目,所以在過濾器中使用'IN'將不起作用,因爲我已經超過了30項/獲取的限制。與AppEngine上的Python和查詢與「IN」範圍

以下是我試圖做一個過濾器:

# addresses come in as list of string items 
addresses = ['123 Main St, Portland, ME', '500 Broadway, New York, NY', ...]; 

query = Event.all(); 
query.filter('location IN ', addresses); 
# above causes the error: 
<class 'google.appengine.api.datastore_errors.BadArgumentError'>: 
Cannot satisfy query -- too many subqueries (max: 30, got 119). 
Probable cause: too many IN/!= filters in query. 

我的模型類:

class Event(GeoModel): 
    name = db.StringProperty(); 
    location = db.PostalAddressProperty(); 

有沒有更好的辦法找到符合特定條件的所有條目?

+1

許多總實體您如何在數據存儲中。在內存中進行過濾幾乎是有意義的,或者如果要匹配的地址列表始終保持相同,則可以執行map-reduce作業以在實體中設置布爾屬性,以顯示實體是否與地址匹配名單。 IN查詢本身實際上在幕後進行了30次查詢;沒有辦法有效地進行這樣的查詢。 – geoffspear

+0

總條目是動態的 - 可能很少,可能會很多。在100 - 10K的範圍內。也許地圖縮小是這項任務的一個好選擇。 –

+0

@DanHolman根據您的使用情況,Map Reduce看起來非常合適。請記住,IN查詢實際上爲每個參數運行1個查詢(因此,30個元素限制),這不僅速度慢,而且對配額使用率有巨大影響。 – marianosimone

回答

3

有比周圍的多個查詢這個其他沒有辦法 - 你畢竟,要求一組不同的地址查詢的綜合結果,這是「IN」的查詢是如何在數據存儲實現。您可能需要考慮使用ndb或異步查詢,以便可以並行運行它們。

或許,如果你解釋你想達到什麼樣的,我們可以提出一個更有效的方法。

0

一個簡單的解決方案/(破解版)將您的地址列表分手到的各30名單。每30個位置執行一次查詢,然後取查詢結果的交集,以獲取原始列表中每個位置的事件。

+0

這就是我正在做的事情,但我想知道是否有更好的方法。 –

-1

GQL「IN」不允許超過30次查詢的詳細爲此,我已劃分的子查詢成小塊爲小於或等於30的子查詢和結果存儲到一個數組。

resultArray = [] 
rLength = 0.0 
rCount = len(subQueryArray) 
rLength = len(subQueryArray)/29.0 
arrayLength = int(math.ceil(rLength)) 
# If subqueries are greater than 30 than divide sub-query length by 29 or 30 
if arrayLength > 1: 
    for ii in range (0, arrayLength): 
#srange = start range, nrange = new range 
if ii == 0: 
    srange = ii 
else: 
    srange = nrange + 1 
nrange = 29 * (ii + 1) 
newList = [] 
for nii in range (srange, nrange+1): 
if nii < rCount: 
    newList.append(subQueryArray[nii]) 
    query = db.GqlQuery(「SELECT * FROM table_name 」 +「WHERE req_id in:1」,newList) 
for result in query.run(): 
# result.id belongs to table entity 
resultArray.append(result.id) 
+0

請正確地縮進您的代碼,您發佈它的方式,此代碼幾乎不可用。 – Holt