首页 文章

在视图上一次查询多个字段

提问于
浏览
1

我有一个场景,其中在我的应用程序中,用户将通过搜索标准进行搜索(例如field1,field2,field3(字段3是日期范围)) . Field1是强制搜索条件,但字段2 ... 5是可选的,它们可以通过用户输入组合 .

所以我创建了一个发出多个键的视图(用户可以搜索的所有可能组合) .

例如:

function (doc, meta) {
if(doc.eventType=='myEvent' && doc.field1){
  if(doc.field2) {
  emit([doc.field1,doc.field2]);
  }
  if(doc.field3) {
  emit(doc.field1,doc.field3]);
  }
  if(doc.field4) {
  emit([doc.field1,doc.field4]);
  }
  if(doc.field5) {
  emit([doc.field1,doc.field5]);
  }
  if(doc.field2 && doc.field3) {
  emit([doc.field1,doc.field2,doc.field3]);
  }
  if(doc.field2 && doc.field4) {
  emit([doc.field1,doc.field2,doc.field4]);
  }
  if(doc.field2 && doc.field5) {
  emit([doc.field1,doc.field2,doc.field5]);
  }
  if(doc.field3 && doc.field4) {
  emit([doc.field1,doc.field3,doc.field4]);
  }
  if(doc.field3 && doc.field5) {
  emit([doc.field1,doc.field3,doc.field5]);
  }
  if(doc.field4 && doc.field5) {
  emit([doc.field1,doc.field4,doc.field5]);
  }
  if(doc.field2 && doc.field3 && doc.field4) {
  emit([doc.field2,doc.field3,doc.field4]);
  }
  if(doc.field2 && doc.field3 && doc.field5) {
  emit([doc.field1,doc.field2,doc.field3,doc.field5]);
  }
  if(doc.field2 && doc.field4 && doc.field5) {
  emit([doc.field1,doc.field2,doc.field4,doc.field5]);
  }
  if(doc.field3 && doc.field4 && doc.field5) {
  emit([doc.field1,doc.field3,doc.field4,doc.field5]);
  }
  if(doc.field2 && doc.field3 && doc.field4 *&& doc.field5) {
  emit([doc.field1,doc.field2,doc.field3,doc.field4,doc.field5]);
  }
}
}

这是正确的方法还是我在这里遗漏了一些东西,因为生成的索引值将是多余的,并且索引文件大小呈指数级增长 .

由于我对Couchbase很新,并且根据我的有限知识,我了解沙发基地不允许在查询中搜索空值?例如,我无法使用单个发射实现上述:

function (doc, meta) {
if(doc.eventType=='myEvent' && doc.field1){
if(doc.field2 && doc.field3 && doc.field4 *&& doc.field5 {
  emit([doc.field1,doc.field2,doc.field3,doc.field4,doc.field5]);
  }
}

该指数 Build 良好 .

但问题在于“查询”该索引,例如对于我具有如上所述的多个搜索标准的场景(即,用户可以提供它们中的一个或它们的组合),通过键/键不可能进行查询 . 另外我可以找到的选项是N1QL,它似乎仍处于开发人员预览状态,所以我认为它不是 生产环境 就绪的 .

有没有其他更好的方法来进行这样的搜索和检索,因为它是一个非常常见的用例,因为我来自一个关系数据库世界,我发现很难得到这个概念,或者我不确定我是否'我在这里遗漏了一些东西,请帮助我,我正在寻找的是一个单一视图的SQL查询,如:

  • where子句中提供的字段可能包含1个或多个值 . 或者他们可能是空的 . 这纯粹基于最终用户输入的搜索条件
select * from view_name where doc.field1="x" and doc.field2 in ("y","z","d") and doc.field3 in ("abc") and Date_column between 2011/02/25 and 2011/02/27 sort by Date_Column desc;

是这样一个上面的查询和检索可能与沙发基础视图和沙发基础客户端Java api .

谢谢 .

1 回答

  • 1

    所以,对你的问题的简短回答是“这是不正确的方法 . ”让我详细说明这一点,首先给出一些背景,然后指出你正确的方向 .

    首先,应该理解Couchbase被设计成一个非常高性能的存储和检索引擎 . 它不是一个高度可搜索的全文数据库 . 在你的第一句话中,你说

    我的应用程序用户将按搜索标准进行搜索

    因此,这导致人们认为Couchbase可能不适合您的场景 . 我说可能是因为Couchbase在任何情况下通常表现都很好,但可能需要一点点(技术术语)来达到目的 .

    您明确指出,您采用的方法不可扩展(在数据中发出可能值的每种组合) . 我会更进一步 . Not only is it not scalable, but you will actually be using the least-performing feature of Couchbase to satisfy the needs of your application. Couchbase索引是基于磁盘的,虽然它们很快,但它们不共享由Couchbase中的memcached支持的vBucket存储机制提供的基于多节点内存的访问,它们也不提供即时一致性或任何其他有用的主要Couchbase平台的功能 .

    因此,你确实面临着选择另一条道路的前景 . 以下是一些可能的选择:

    • Use a SQL database :此选项不言自明 . 您将获得SQL的优点和缺点 .

    • Application-side Joins: 使用这种方法,您的应用程序可以容忍过时的索引,并且在搜索中只有合理的最新结果(合理的是1-5分钟,平均最差情况) . 您为感兴趣的每个字段创建单独的索引 . 然后,当查询出现时,您将查找数据抽象层中索引之间的交叉点 . 例如,

    select * from view_name 
        where doc.field1="x"
          and doc.field2 in ("y","z","d") 
          and doc.field3 in ("abc") 
          and Date_column between 2011/02/25 and 2011/02/27
        sort by Date_Column desc;
    

    这实际上需要四个独立的指数 . 在您的应用程序中,首先搜索最严格的索引,然后查看剩余索引以构建结果集,最后对输出进行排序并发送到客户端 . 你做了SQL数据库通常会做的工作,但是你正在使用Couchbase,因此它超级快,而且你没有得到SQL数据库给你的任何神奇的废话 .

    • Use N1QL: 这是一种基于sql的查询语言,构建于Couchbase之上 . 在引擎盖下,它执行与选项2类似的操作,但是这一切都适合您 .

    • Use Elasticsearch: 这是最好的全文搜索noSql数据存储之一 . 它的架构非常类似于Couchbase,除了基于内存的访问,Elasticsearch使用Lucene索引来实现非常快速的全文搜索 . 在你拥有的地方使用它复杂的多属性文档,您希望对无限的查询集进行高性能搜索 . Couchbase甚至有一个将数据转储到Elasticsearch集群的plugin,因此您可以轻松地获得两个平台的优势 .

    Option 4 is probably your best option under any scenario, but it is up to you to weigh the pros and cons of your specific use-case to determine the best path forward.

相关问题