首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ektorp CouchDb:多个包含模式的查询

Ektorp CouchDb:多个包含模式的查询
EN

Stack Overflow用户
提问于 2016-05-11 20:21:52
回答 1查看 820关注 0票数 1

我想要查询多个候选的搜索字符串,该字符串看起来像"My“。现在,我想找一些文档,其中有一个字段,其中包含一个(或多个)输入字符串的(被空格拆分)。

我找到了一些允许我按模式进行搜索的代码:

代码语言:javascript
复制
@View(name = "find_by_serial_pattern", map = "function(doc) { var i; if(doc.serialNumber) { for(i=0; i < doc.serialNumber.length; i+=1) { emit(doc.serialNumber.slice(i), doc);}}}")
public List<DeviceEntityCouch> findBySerialPattern(String serialNumber) {
    String trim = serialNumber.trim();

    if (StringUtils.isEmpty(trim)) {
        return new ArrayList<>();
    }
    ViewQuery viewQuery = createQuery("find_by_serial_pattern").startKey(trim).endKey(trim + "\u9999");

    return db.queryView(viewQuery, DeviceEntityCouch.class);
}

这对于寻找一种模式来说是很不错的。但是,如何修改代码才能在doc.serialNumber上获得多个包含?

编辑:--这是当前的解决办法,但我想肯定有更好的方法。而且只有一个或逻辑。因此,一个条目适合在列表中的term1或term2。

代码语言:javascript
复制
@View(name = "find_by_serial_pattern", map = "function(doc) { var i; if(doc.serialNumber) { for(i=0; i < doc.serialNumber.length; i+=1) { emit(doc.serialNumber.slice(i), doc);}}}")
public List<DeviceEntityCouch> findBySerialPattern(String serialNumber) {
    String trim = serialNumber.trim();

    if (StringUtils.isEmpty(trim)) {
        return new ArrayList<>();
    }

    String[] split = trim.split(" ");

    List<DeviceEntityCouch> list = new ArrayList<>();
    for (String s : split) {
        ViewQuery viewQuery = createQuery("find_by_serial_pattern").startKey(s).endKey(s + "\u9999");
        list.addAll(db.queryView(viewQuery, DeviceEntityCouch.class));
    }

    return list;
}
EN

回答 1

Stack Overflow用户

发布于 2016-05-12 02:59:37

看起来您正在这里实现全文搜索。这在CouchDB中不太有效(我想其他数据库也是如此)。

如果我错了,请纠正我,但是从你的代码来看,你似乎是在试图搜索一个模式的序列号列表。如果您可以以某种方式索引要搜索的数据,CouchDB (或任何其他数据库)是非常有效的。否则,您必须获取每个记录并对其执行字符串比较。

我认为在CouchDB中优化这一点的唯一方法是(假设)如下所示:

  1. 你的序列号不是很长(比如说20个字符?)
  2. 强制搜索始终为5个字符。
  3. 生成视图,该视图从序列号中释放每一个5个字符长的子字符串--或多或少是这样(可以进行优化,并且不确定是否得到了in): ..。(var i= 0;doc.serialNo.length >5 && i++;doc.serialNo.length - 5;i++) { emit(doc.serialNo.substring(i,i+ 5),doc._id);}.
  4. 使用_count约简函数

下面的网址是:

代码语言:javascript
复制
http://localhost:5984/test/_design/serial/_view/complex-key?startkey=["01234"]&endkey=["01234",{}]&group=true

将返回具有01234键的命中计数的文档列表。如果不分组并将减值选项设置为false,则将得到所有匹配的列表,如果单个文档有多个命中,则包括重复匹配。有关复杂键查找的信息,请参阅http://ryankirkman.com/2011/03/30/advanced-filtering-with-couchdb-views.html

我不确定couchdb更新该视图的效率有多高。这取决于您将拥有多少记录,以及在视图之间查询了多少新条目(我了解couchdb根据需要重新构建视图的b树)。

我已经生成了这样一个视图,它将文档I拆分为5个字符长键。在超过1K的文档中,它产生了超过30K的结果-- id是32个字符长,简单的数学:(serialNo.length - searchablekey.length + 1) * docscount)。生成视图需要一段时间,但是查找速度很快。

您可以生成多个长度的键,等等。所有这些都取决于您的记录、计数和查找速度。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37172582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档