Lucene 高性能的唯一文档id检索
目前,我正在Java平台上使用Lucene 4.9.0开发高性能NRT系统,该系统可以检测几乎重复的文本文档 为此,我查询Lucene以返回一些匹配的候选项集,并在本地执行近似重复的计算(通过检索和缓存术语向量)。但我主要关心的是将Lucene的docId(可以更改)绑定到我自己存储在索引中的唯一且不可变的文档id的性能问题 我的流程如下:Lucene 高性能的唯一文档id检索,lucene,Lucene,目前,我正在Java平台上使用Lucene 4.9.0开发高性能NRT系统,该系统可以检测几乎重复的文本文档 为此,我查询Lucene以返回一些匹配的候选项集,并在本地执行近似重复的计算(通过检索和缓存术语向量)。但我主要关心的是将Lucene的docId(可以更改)绑定到我自己存储在索引中的唯一且不可变的文档id的性能问题 我的流程如下: Lucene中的文档查询 对于每个文件: 基于Lucene docId获取我的唯一文档id 从缓存中获取我的文档id的术语向量(如果它不存在-从Luce
- Lucene中的文档查询
- 对于每个文件:
- 基于Lucene docId获取我的唯一文档id
- 从缓存中获取我的文档id的术语向量(如果它不存在-从Lucene获取它并填充缓存)
- 做数学
- 尝试使用Zoie处理唯一和持久的文档标识符
- 使用FieldCache(仍然非常低效)
- 有效载荷的使用(根据)-但我不知道如何应用它
还有其他建议吗?我已经找到了如何利用Lucene的AtomicReader的优势部分解决这个问题的方法。为此,我使用全局缓存来保持已经实例化的段的FieldCache
Map<Object, FieldCache.Ints> fieldCacheMap = new HashMap<Object, FieldCache.Ints>();
Map fieldCacheMap=newhashmap();
在我的方法中,我使用以下代码:
Query query = new TermQuery(new Term(FIELD_NAME, fieldValue));
IndexReader indexReader = DirectoryReader.open(indexWriter, true);
List<AtomicReaderContext> leaves = indexReader.getContext().leaves();
// process each segment separately
for (AtomicReaderContext leave : leaves) {
AtomicReader reader = leave.reader();
FieldCache.Ints fieldCache;
Object fieldCacheKey = reader.getCoreCacheKey();
synchronized (fieldCacheMap) {
fieldCache = fieldCacheMap.get(fieldCacheKey);
if (fieldCache == null) {
fieldCache = FieldCache.DEFAULT.getInts(reader, ID_FIELD_NAME, true);
fieldCacheMap.put(fieldCacheKey, fieldCache);
}
usedReaderSet.add(fieldCacheKey);
}
IndexSearcher searcher = new IndexSearcher(reader);
TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (int i = 0; i < scoreDocs.length; i++) {
int docID = scoreDocs[i].doc;
int offerId = fieldCache.get(docID);
// do your processing here
}
}
// remove unused entries in cache set
synchronized(fieldCacheMap) {
Set<Object> inCacheSet = fieldCacheMap.keySet();
Set<Object> toRemove = new HashSet();
for(Object inCache : inCacheSet) {
if(!usedReaderSet.contains(inCache)) {
toRemove.add(inCache);
}
}
for(Object subject : toRemove) {
fieldCacheMap.remove(subject);
}
}
indexReader.close();
Query Query=新术语查询(新术语(字段名称,字段值));
IndexReader IndexReader=DirectoryReader.open(indexWriter,true);
List leaves=indexReader.getContext().leaves();
//分别处理每个段
for(AtomicReaderContext离开:离开){
AtomicReader=leave.reader();
Ints FieldCache;
Object fieldCacheKey=reader.getCoreCacheKey();
已同步(fieldCacheMap){
fieldCache=fieldCacheMap.get(fieldCacheKey);
if(fieldCache==null){
fieldCache=fieldCache.DEFAULT.getInts(读卡器,ID\u FIELD\u NAME,true);
fieldCacheMap.put(fieldCacheKey,fieldCache);
}
UseDrawerSet.add(fieldCacheKey);
}
IndexSearcher search=新的IndexSearcher(阅读器);
TopDocs TopDocs=searcher.search(查询,整数.MAX_值);
ScoreDoc[]scoreDocs=topDocs.scoreDocs;
for(int i=0;i
它工作得相当快。我主要关心的是内存使用率,当使用大索引时,内存使用率可能非常高
Query query = new TermQuery(new Term(FIELD_NAME, fieldValue));
IndexReader indexReader = DirectoryReader.open(indexWriter, true);
List<AtomicReaderContext> leaves = indexReader.getContext().leaves();
// process each segment separately
for (AtomicReaderContext leave : leaves) {
AtomicReader reader = leave.reader();
FieldCache.Ints fieldCache;
Object fieldCacheKey = reader.getCoreCacheKey();
synchronized (fieldCacheMap) {
fieldCache = fieldCacheMap.get(fieldCacheKey);
if (fieldCache == null) {
fieldCache = FieldCache.DEFAULT.getInts(reader, ID_FIELD_NAME, true);
fieldCacheMap.put(fieldCacheKey, fieldCache);
}
usedReaderSet.add(fieldCacheKey);
}
IndexSearcher searcher = new IndexSearcher(reader);
TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (int i = 0; i < scoreDocs.length; i++) {
int docID = scoreDocs[i].doc;
int offerId = fieldCache.get(docID);
// do your processing here
}
}
// remove unused entries in cache set
synchronized(fieldCacheMap) {
Set<Object> inCacheSet = fieldCacheMap.keySet();
Set<Object> toRemove = new HashSet();
for(Object inCache : inCacheSet) {
if(!usedReaderSet.contains(inCache)) {
toRemove.add(inCache);
}
}
for(Object subject : toRemove) {
fieldCacheMap.remove(subject);
}
}
indexReader.close();