2015-03-31 47 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,则可以获得良好的性能。