2009-09-30 70 views
4

我正在使用帶有JDO的Google App Engine(Java)。我該如何做JDO等價物使用Google App Engine和JDO的全文搜索?

select * from table where field like '%foo%' 

我目前看到的唯一建議是使用Lucene。我有點驚訝,這種基本的功能在開箱即用的GAE上是不可能的。

回答

6

您不能在App Engine上進行該類型的子字符串搜索。原因是App Engine數據存儲的構建是可擴展的,並拒絕執行它無法滿足索引的任何查詢。索引這樣的查詢幾乎是不可能的,因爲它需要搜索每個記錄的「字段」屬性的全部匹配。任何運行此查詢的關係數據庫都將通過執行全表掃描並單獨檢查每個記錄來執行它 - 不可伸縮的,至少可以說。

正如你已經發現的,解決方案是使用全文索引,比如Lucene。在App Engine上有用於運行Lucene的庫,例如GAELucene。這也給你適當的全文搜索的力量,而不是天真的子串匹配。

+0

尼克,感謝您的答覆。數據存儲可以創建單個詞的索引,而不是%foo%?我的意思是,Google顯然能夠進行關鍵字搜索,如果不是類似於正則表達式的搜索。 我真正想要完成的是掃描一組關鍵字的食譜,所以也許我制定了我的問題很差。謝謝。 – 2009-09-30 15:41:51

+1

是的 - 你所指的是被稱爲「倒排索引」 - 這就是Lucene使用的庫。對於Python,有SearchableModel,它實現了這種模式。如果你願意,你可以在Java中做同樣的事情,但是使用Lucene可能會更好。 – 2009-09-30 16:54:15

1

tl; dr:管理您自己的多值搜索屬性並對其執行等值查詢。

詳情: 對於那些尋找一些簡單的DIY,你可以做到以下幾點:

  1. 在你的實體,創建一個多值searchTerms財產。這將包含實體的可搜索項目。

  2. 將實體的可搜索文本拆分爲單詞。這些詞將是實體唯一可搜索的部分。你可以先分開空白,或者你可以添加一些基本的詞幹。例如。在處理電子郵件地址時,您可能需要分別放置用戶和域部分,以便可以搜索這兩部分。如果你的實體更新,你需要重建這個屬性。

  3. 要執行搜索,請將搜索輸入拆分爲單詞(如果需要,請執行基本詞根分析),並使用等於運算符將每個詞作爲過濾器添加到searchTerms屬性中。

    (多值屬性上的=運算符詢問的任何值是否等於過濾器。)

    E.g. (使用Objectify):

    Query query = dao.ofy().query(Recipe.class); 
    for (String term : search.toLowerCase().split(" ")) { 
        query = query.filter("searchTerms =", term); 
    } 
    

相關問題