这是我在 sql 中需要的示例:
SELECT name FROM employ WHERE name LIKE %bro%
如何在 CouchDB 中创建这样的 View ?
最佳答案
简单的答案是 CouchDB View 对此并不理想。
更复杂的答案是,这种类型的查询在典型的 SQL 引擎中往往也非常低效,因此如果您承认与任何解决方案之间存在权衡,那么 CouchDB 实际上具有优势让您选择权衡。
1. SQL 方式
当您执行 SELECT ... WHERE name LIKE %bro%
时,我熟悉的所有 SQL 引擎都必须执行所谓的“全表扫描”。这意味着服务器读取相关表中的每一行,然后强力扫描该字段以查看它是否匹配。
您可以在 CouchDB 2.x 中使用 $regex
operator 的 Mango 查询来执行此操作.对于基本情况,查询看起来像这样:
{"selector":{
"name": {
"$regex": "bro"
}
}}
似乎没有公开任何区分大小写等选项,但您可以将其扩展为仅匹配开头/结尾或更复杂的模式。如果您还可以通过其他一些(可索引的)字段运算符限制您的查询,那可能有助于提高性能。正如文档警告:
Regular expressions do not work with indexes, so they should not be used to filter large data sets. […]
您也可以在 CouchDB 1.x 中进行全面扫描,使用 temporary view :
POST /some_database/_temp_view
{"map": "function (doc) { if (doc.name && doc.name.indexOf('bro') !== -1) emit(null); }"}
这将查看数据库中的每一个文档,并为您提供匹配文档的列表。您可以调整 map 函数以匹配文档类型,或者使用特定的键进行排序 — emit(doc.timestamp)
— 或者一些对您的目的有用的数据值 — emit(null, doc.name)
.
2。 “大量可用磁盘空间”方式
根据您的源数据大小,您可以创建一个索引,该索引发出每个可能的“内部字符串”作为其永久(磁盘上) View 键。也就是说,对于像“Dobros”这样的名称,您会 emit("dobros");发出(“奥布罗斯”);发出(“兄弟”);发出(“ros”);发出(“操作系统”);发出(“s”);
。然后对于像 '%bro%' 这样的术语,您可以使用 startkey="bro"&endkey="bro\uFFFF"
查询您的 View 以获取所有出现的查找术语。您的索引将大约是您的文本内容的大小平方,但是如果您需要比上面的完整数据库扫描更快地执行任意“在字符串中查找”并且有空间,这可能会起作用。为 substring searching 设计的数据结构会更好地为您服务虽然。
这也给我们带来了...
3。 全文检索方式
您可以使用 CouchDB 插件(couchdb-lucene 现在通过 Dreyfus/Clouseau for 2.x, ElasticSearch , SQLite's FTS )在您的文档中生成辅助的面向文本的索引。
请注意,大多数全文搜索索引 don't naturally support任意通配符前缀,可能出于与我们上面看到的类似的空间效率原因。通常全文搜索并不意味着“暴力二进制搜索”,而是“单词搜索”。不过,YMMV,看看全文引擎中可用的选项。
如果您真的不需要在某个字段中任何地方查找“bro”,您可以使用常规 CouchDB View 实现基本的“查找以 X 开头的单词”搜索,只需拆分不同的语言环境即可-特定的单词分隔符并省略这些“单词”作为您的 View 键。这将比上面更有效,根据索引的数据量按比例缩放。
关于javascript - 如何在 CouchDB 中创建 "like"过滤器 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5509911/