我想查询多个候选人以查找类似“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;
}
答案 0 :(得分:0)
看起来您正在此处实施全文搜索。这在CouchDB中不会非常有效(我猜这同样适用于其他数据库)。
如果我错了,请纠正我,但是从查看代码看起来就像是在尝试搜索模式的序列号列表。如果您可以以某种方式索引要搜索的数据,那么CouchDB(或任何其他数据库)非常有效。 否则,您必须获取每个记录并对其执行字符串比较。
我能想到在CouchDB中优化这个的唯一方法就是以下(假设):
生成视图,从序列号中发出每个5个字符长的子字符串 - 或多或少这个(可以优化,不确定我是否进入):
...
for (var i = 0; doc.serialNo.length > 5 && i < doc.serialNo.length - 5; i++) {
emit([doc.serialNo.substring(i, i + 5), doc._id]);
}
...
使用_count
缩减功能
现在提供以下网址:
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)。 生成视图需要一段时间,但查找速度很快。
您可以生成多种长度的密钥等。所有这些都归结为您的记录数量与查找速度。