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

时间:2016-05-11 20:21:53

标签: java search couchdb ektorp

我想查询多个候选人以查找类似“My sear foo”的搜索字符串。 现在我想查找具有包含一个(或多个)输入字符串的字段的文档(看作由空格分割)。

我发现了一些允许我按照模式进行搜索的代码:

@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上的多个包含?

修改 这是当前的解决方法,但我必须有更好的方法。 此外,只有OR逻辑。因此,条目使term1或term2适合列表。

@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;
}

1 个答案:

答案 0 :(得分:0)

看起来您正在此处实施全文搜索。这在CouchDB中不会非常有效(我猜这同样适用于其他数据库)。

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

我能想到在CouchDB中优化这个的唯一方法就是以下(假设):

  1. 您的序列号不是很长(比如20个字符?)
  2. 您强制搜索始终为5个字符
  3. 生成视图,从序列号中发出每个5个字符长的子字符串 - 或多或少这个(可以优化,不确定我是否进入):

    ...
    for (var i = 0; doc.serialNo.length > 5 && i < doc.serialNo.length - 5; i++) {
        emit([doc.serialNo.substring(i, i + 5), doc._id]);
    }
    ...
    
  4. 使用_count缩减功能

  5. 现在提供以下网址:

    http://localhost:5984/test/_design/serial/_view/complex-key?startkey=["01234"]&endkey=["01234",{}]&group=true
    

    将返回一个文件列表,其中包含01234键的点击计数。 如果您不对reduce选项进行分组并将其设置为false,则会获得所有匹配项的列表,如果单个文档具有多个匹配项,则包括重复项。 有关复杂键查找的信息,请参阅http://ryankirkman.com/2011/03/30/advanced-filtering-with-couchdb-views.html

    我不确定在更新该视图方面,couchdb的效率如何。这取决于您将拥有多少条记录以及查询视图之间出现的新条目数量(我理解couchdb会根据需要重建视图的b-tree)。

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

    您可以生成多种长度的密钥等。所有这些都归结为您的记录数量与查找速度。