基于布隆过滤器快速匹配敏感词、关键词、品牌词
使用
- 如果要和类目关联,在品牌词加表示-类目,查询的时候补上类目即可
- 原词要进行穷举比如 1 2 3,形成 1,2,3,12,23,123 进行匹配
- 大小写的话直接插入和查询的适合自己提前先转换一下即可
- 800w 数据占用 20mb 内存,200 条数据 3ms 出结果
package cn.hutool.dfa;
import cn.hutool.bloomfilter.BitMapBloomFilter;
import cn.hutool.core.thread.ThreadUtil;
import org.junit.Before;
import org.junit.Test;
import org.python.sizeof.RamUsageEstimator;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class BloomFilterTreeTest {
BitMapBloomFilter filter = new BitMapBloomFilter(20);
Set<String> set = new LinkedHashSet<>();
List<String> realsTest = Arrays.asList(");
@Before
public void generateCombinations() {
// 开始时间
long start = System.currentTimeMillis();
String input = "NICK nick优质品牌";
int length = input.length();
// 穷举
for (int i = 1; i <= length; i++) {
for (int j = 0; j <= length - i; j++) {
String combination = input.substring(j, j + i);
set.add(combination);
}
}
// 结束时间
long end = System.currentTimeMillis();
System.out.println("生成组合耗时:" + (end - start));
int count = (length * (length + 1)) / 2;
System.out.println("生成组合数:" + count);
System.out.println(set);
}
@Test
public void matchAllTest() {
// 开始时间
long start = System.currentTimeMillis();
// 读取当前目录下.word.txt,然后分割字符串,然后添加到查询树中
String filePath = "/Users/wss/develop/AiyongCode/shopDepart/hutool/hutool-dfa/src/test/java/cn/hutool/dfa/itembrands.txt"; // 替换为你的文本文件路径
try {
String content = new String(Files.readAllBytes(Paths.get(filePath)));
// 读取时间
long read = System.currentTimeMillis();
// 读取耗时
System.out.println("读取耗时:"+ (read - start));
String[] array = content.split(",");
// size
System.out.println("size:" + array.length);
Arrays.stream(array).forEach(word -> filter.add(word));
// 加载时间
long load = System.currentTimeMillis();
System.out.println("加载耗时:" + (load - read));
realsTest.forEach(str -> System.out.println(str + " real result " + filter.contains(str)));
// 计算时间 计算耗时
long end = System.currentTimeMillis();
System.out.println("计算耗时:" + (end - load));
System.out.println("filter 占用内存:" + RamUsageEstimator.humanSizeOf(filter));
// 计算 set 占用
System.out.println("set 占用内存:" + RamUsageEstimator.humanSizeOf(set));
// set计算开始时间
long setStart = System.currentTimeMillis();
// set判断 布隆
set.forEach(str -> System.out.println(str + " result " + filter.contains(str)));
// set计算结束时间
long setEnd = System.currentTimeMillis();
System.out.println("set 计算耗时:" + (setEnd - setStart));
} catch (IOException e) {
e.printStackTrace();
}
}
}
数据量大加载慢
多线程加载
10% 左右优化,效果不佳
List<String> array = Arrays.*asList*(content.split(","));
*array.parallelStream().forEach(word -> filter.add(word));*
加载后数据持久化(持久化存储读取加载)
# guava 有提供
filter.writeTo();
BloomFilter.*readFrom*()