为Aerospike实现LIKE查询运算符

时间:2016-04-19 15:01:57

标签: full-text-search user-defined-functions aerospike

我是Aerospike的新人。有没有简单的方法来搜索像Mysql这样的文本的一部分。例如:

select * from test where column like '%hello%';

如果不支持此常见操作,我发现难以迁移到NoSQL数据库。 感谢。

1 个答案:

答案 0 :(得分:2)

Predicate filtering中添加了

release 3.12。您可以使用Java客户端的stringRegex类的PredExp方法来实现LIKE的等效方法。谓词过滤器目前也适用于CC#Go个客户。

Aerospike Java客户端中的example显示了类似的内容:

    Statement stmt = new Statement();
    stmt.setNamespace(params.namespace);
    stmt.setSetName(params.set);        
    stmt.setFilter(Filter.range(binName, begin, end));
    stmt.setPredExp(
        PredExp.stringBin("bin3"),
        PredExp.stringValue("prefix.*suffix"),
        PredExp.stringRegex(RegexFlag.ICASE | RegexFlag.NEWLINE)
        );

如果您使用的语言客户端尚不支持谓词过滤,则可以使用附加到扫描或查询的stream UDF来实现此功能。例如,在Python客户端中,您将创建具有或不具有谓词的类aerospike.Query的实例,并调用aerospike.Query.apply()方法。

理想情况下,您可以通过分段和使用谓词来缩小搜索范围来加快速度,而不是扫描整个集合。例如,您可以创建包含第一个字母的startswith bin,使用谓词查找,然后发送通过流UDF匹配的记录。请注意,LIKE在RDBMS上的运行速度非常慢,因为它不能使用索引。

local function bin_like(bin, val, plain)
    return function(rec)
        if rec[bin] and type(rec[bin]) == "string" then
            if string.find(rec[bin], val, 1, plain) then
                return true
            else
                return false
        else
            return false
        end
    end
end

local function map_record(rec)
  local ret = map()
  for i, bin_name in ipairs(record.bin_names(rec)) do
    ret[bin_name] = rec[bin_name]
  end
  return ret
end

function check_bins_match(stream, bin, val, plain)
  return stream : filter(bin_like(bin, val, plain)) : map(map_record)
end