2015-03-31 14 views
1

我有一個動態查詢,我想使用PouchDB編寫,但我發現很難翻譯我如何使用SQL數據庫與PouchDB相比實現此功能。如何使用pouchdb創建動態查詢(couchdb可能是同一件事)?

我在PouchDB中有多少類型爲'session'的文檔,並且需要對這種類型的文檔進行復雜的搜索。我想過濾標題(以提供的值開頭的字符串),狀態,所有者,設備ID,開始日期,結束日期以及其他一些內容。

現在,我知道我可以發出一個數組鍵,喜歡的東西:

  document.views = { 
       by_title_status_owner: { 
        map: function(document) { 
         if(document._id.startsWith('session')) { 
          emit([ 
           document.title.toUpperCase(), 
           document.status.text.toUpperCase(), 
           document.owner.refId 
          ], null); 
         } 
        }.toString() 
       } 
      }; 

我的問題是,我不知道如何讓使用startkeyendkey查詢。我想這樣的東西:

   startkey: [ 
        (filters.title || '').toUpperCase(), 
        (filters.status || '').toUpperCase(), 
        (filters.owner || '') 
       ], 
       endkey: [ 
        (filters.title || '').toUpperCase() + '\uffff', 
        (filters.status || '').toUpperCase() + '\uffff', 
        (filters.owner || '').toUpperCase() + '\uffff' 
       ], 

但似乎只對第一指標篩選 - 這意味着它是正確過濾的標題,但狀態或所有者搜索時,查詢將返回所有的結果。

我認爲問題在於我真的想提供不同的排列數組鍵,並根據用戶輸入的內容提供不同的startkey/endkey組合,但這對PouchDB來說似乎非常困難。

例如,假設用戶在'Lig'中鍵入了他們的title搜索,並且選擇了CLOSED作爲狀態。這意味着startkey應該看起來像['LIG','CLOSED'],endkey可能看起來像['LIG \ uffff','CLOSED']。但是這是否意味着我必須發出關鍵索引的每一個排列來匹配這個動態的startkey/endkey?

這是我的第一次嘗試,而我還沒有加入2+參數emited鍵.....

 getAllByCriteria: function(filters) { 
      var startkey = [], endkey = []; 

      if(filters.title) { 
       startkey.push((filters.title || '').toUpperCase()); 
       endkey.push((filters.title || '').toUpperCase() + '\uffff'); 
      } 

      if(filters.status) { 
       startkey.push((filters.status).toUpperCase()); 
       endkey.push((filters.status).toUpperCase()); 
      } 

      if(filters.owner) { 
       startkey.push(filters.owner); 
       endkey.push(filters.owner); 
      } 

      return Database.instance().query('session_indexes/by_criteria', { 
       startkey: startkey, 
       endkey: endkey, 
       include_docs: true 
      }).then(function(result) { 
       return _(result.rows).map(function(row) { 
        return Session.fromDocument(row.doc, new Session()); 
       }); 
      }); 
     }, 

和:

 db.upsert('_design/session_indexes', function(document) { 
      document.views = { 
       by_criteria: { 
        map: function(document) { 
         if(document._id.startsWith('session')) { 
          emit([], null) 
          emit([document.title.toUpperCase()], null); 
          emit([document.status.text.toUpperCase()], null); 
          emit([document.owner.refId], null); 
         } 
        }.toString() 
       } 
      }; 

      return document; 
     }); 

我真的困惑。我會很感激任何幫助。

謝謝!

回答

0

您可以使用視圖和列表的組合。

  1. ["title", doc.title.toUpperCase()]["status", doc.status.toUpperCase()]的Emit按鍵使用地圖FN,說indexfn

  2. 創建_list fn,例如filter,它接受像{field1:"value1", field2:"value2"...}這樣的查詢 - 列表可以接收與地圖fns不同的自定義查詢參數。如果過濾器不匹配,則必須刪除行。當然,爲了使過濾成爲可能,您的_list必須從視圖fn收到全部(或以某種方式修剪)一組字段。

  3. /_design/ddoc/_list/filter/_view/indexfn?startkey=["field1","val1"] & endkey=["field1","val1z"] & filter={"field2":"val2", "field3":"val3"}

執行請求時,你_list接收,也就是說,不是從查看更多然後1000行這種做法是合理的 - 管道數據從視圖中通過Fn鍵,最終用戶是安靜緩慢_lists。

因此,如果您擁有大約1M記錄的模糊分佈數據集,並且發送長度爲3個或更多字符的startkey,則可以獲得良好的性能。