`
madbluesky
  • 浏览: 83738 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

基于倒排索引的缓存对象索引通用解决方案

    博客分类:
  • java
阅读更多

一个给javabean列表建立倒排索引的通用类,主要可用于给缓存中的一类对象添加索引便于搜索,对于缓存中的对象实现模糊搜索是一种非常合适的方案

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class InvertedIndexGeneric<T> {
	/**
	 * 索引
	 */
	private Map<String, List<T>> invertedIndex = new HashMap<String, List<T>>();
	/**
	 * 缓存的待索引项
	 */
	private Map<String, T> invertedIndexItemsMap = new HashMap<String, T>();

	/**
	 * 主键属性的get方法
	 */
	private Method prekeyMethod;
	/**
	 * 被索引属性的get方法
	 */
	private Method indexedAttrMethod;

	private Class<T> beanClass;

	/**
	 * 
	 * @param beanList
	 *            待索引javabean列表
	 * @param targetBeanClass
	 *            待索引javabean类型
	 * @param preKeyAttr
	 *            待索引项唯一标识(主键)的javabean属性名
	 * @param indexedAttr
	 *            待索引项的附加索引的javabean属性名
	 */
	public InvertedIndexGeneric(List<T> beanList, Class<T> targetBeanClass,
			String preKeyAttr, String indexedAttr) {
		if (beanList == null || beanList.size() == 0) {
			throw new RuntimeException("待索引项为空!");
		}
		this.beanClass = targetBeanClass;
		this.prekeyMethod = this.buildAttrGetMethod(preKeyAttr);
		this.indexedAttrMethod = this.buildAttrGetMethod(indexedAttr);
		for (T invertedIndexAble : beanList) {
			invertedIndexItemsMap
					.put(this.getIndexedBeanPrekey(invertedIndexAble),
							invertedIndexAble);
		}
		this.buildInverteIndex();
	}

	/**
	 * 查询键值相关的索引项
	 * 
	 * @param key
	 *            关键字
	 * @return 键值相关的索引项
	 */
	public synchronized List<T> find(String key) {
		return invertedIndex.get(key);
	}

	/**
	 * 增加待索引项
	 * 
	 * @param item
	 *            待索引项
	 */
	public synchronized void addInvertItem(T item) {
		List<String> keys = getAllKeys(this.getIndexedAttrValue(item));
		for (int i = 0; i < keys.size(); i++) {
			String key = keys.get(i);
			List<T> linkedIndexAbles = invertedIndex.get(key);
			if (linkedIndexAbles != null) {
				for (T varIndexAble : linkedIndexAbles) {
					if (varIndexAble.equals(item)) {
						continue;
					}
				}
				linkedIndexAbles.add(item);
			} else {
				List<T> indexAbles = new ArrayList<T>();
				indexAbles.add(item);
				invertedIndex.put(key, indexAbles);
			}
		}
	}

	/**
	 * 删除待索引项
	 * 
	 * @param beanPreKey
	 *            可索引项的主键
	 */
	public synchronized void deleteInvertedItem(String beanPreKey) {
		T invertedIndexAble = invertedIndexItemsMap.get(beanPreKey);
		List<String> keys = getAllKeys(this
				.getIndexedAttrValue(invertedIndexAble));
		for (int i = 0; i < keys.size(); i++) {
			String key = keys.get(i);
			List<T> linkedIndexAbles = invertedIndex.get(key);
			if (linkedIndexAbles != null && linkedIndexAbles.size() > 0) {
				for (T varTItem : linkedIndexAbles) {
					if (this.getIndexedBeanPrekey(varTItem).equals(beanPreKey)) {
						linkedIndexAbles.remove(varTItem);
						break;
					}
				}
			}
			if (linkedIndexAbles.size() <= 0) {
				invertedIndex.remove(key);
			}
		}
	}

	/**
	 * 更新可索引项
	 * 
	 * @param bean
	 *            可索引项
	 */
	public synchronized void updateInvertedItem(T bean) {
		T oldItem = invertedIndexItemsMap.get(this.getIndexedBeanPrekey(bean));
		if (oldItem != null) {
			this.deleteInvertedItem(this.getIndexedBeanPrekey(oldItem));
			this.addInvertItem(bean);
		}
	}

	/**
	 * 构建索引
	 */
	private synchronized void buildInverteIndex() {
		for (T bean : invertedIndexItemsMap.values()) {
			this.addInvertItem(bean);
		}
	}

	/**
	 * 找出一个字符串所有的可能的倒排索引的键列表
	 * 
	 * @param str
	 *            字符串
	 * @return 一个字符串所有的可能的倒排索引的键列表
	 */
	private List<String> getAllKeys(String str) {
		List<String> result = new ArrayList<String>();
		char[] chars = str.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			String key = "";
			for (int j = i; j < chars.length; j++) {
				key = key + chars[j];
				result.add(key);
			}
		}
		return result;
	}

	private String getIndexedBeanPrekey(T bean) {
		try {
			return this.prekeyMethod.invoke(bean).toString();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private String getIndexedAttrValue(T bean) {
		try {
			return this.indexedAttrMethod.invoke(bean).toString();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private Method buildAttrGetMethod(String attrName) {
		String firstLetter = attrName.substring(0, 1);
		firstLetter = firstLetter.toUpperCase();
		String methodName = "get" + firstLetter + attrName.substring(1);
		Method method = null;
		try {
			method = this.beanClass.getMethod(methodName);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return method;
	}
}

 

分享到:
评论

相关推荐

    亿级数据的高并发通用搜索引擎架构设计[转载]

    综上所述,构建亿级数据的高并发通用搜索引擎架构涉及多个层面的技术,包括倒排索引、分布式系统、负载均衡、缓存策略、数据存储、实时处理以及智能排序等。每个环节都至关重要,需要根据具体业务需求进行精细化设计...

    基于PHP的Sou垂直搜索引擎GBK源码.zip

    1. **全文检索技术**:搜索引擎的核心是全文检索,它需要解析和索引文本内容,如使用倒排索引技术,以便快速查找含有特定关键词的文档。 2. **分词技术**:在中文环境下,搜索引擎需要进行分词处理,将连续的汉字...

    ASP.NET源码——[搜索链接]网博垂直搜索引擎完全开源版.zip

    3. **索引构建(Indexing)**:构建索引是搜索引擎的核心部分,它将预处理后的数据组织成高效的查询结构,如B树、倒排索引等。这部分代码会涉及到数据结构和算法的运用。 4. **查询处理(Query Processing)**:...

    通用大数据存储和分析处理平台-Hadoop.docx

    - **Bloom filter**、**Hashing**、**bit-map**、**堆**、**双层桶划分**、**数据库索引**(如倒排索引)、**外排序**、**trie 树**等是处理大数据时的常用技术策略。 7. **配置调优**: - **MapReduce配置**:...

    概要设计1

    3. **网页解析与内容抽取**:解析网页结构,提取主要内容和超链接,这些信息是建立倒排索引的基础。 4. **倒排索引**:一种高效的数据结构,用于存储网页内容,以支持快速查询。它将每个单词映射到包含该词的文档...

    实现跨框架的类似GOOGLE的搜索建议

    常见的有Trie树,AC自动机(Aho-Corasick Algorithm),或者基于倒排索引的搜索算法。这些算法可以在短时间内找出与输入关键词匹配的建议。 4. **数据存储与索引**:数据通常存储在数据库中,如MySQL, PostgreSQL,...

    ASP源码—奥搜垂直搜索引擎.zip

    这部分源码会涉及到如何抓取、存储和更新数据,以及如何构建倒排索引。 4. **相关性排名算法**:为了返回最相关的搜索结果,搜索引擎需要应用排序算法,如TF-IDF(词频-逆文档频率)、PageRank等。奥搜的源码可能...

    ASP.NET-[搜索链接]易搜索站内全文检索搜索引擎v1.0.zip

    这可能依赖于高效的搜索算法,如倒排索引,以及可能的缓存策略来提高性能。 3. **模糊匹配**:易搜索可能支持模糊匹配,允许用户输入不完全准确的关键词也能找到相关结果。这可能涉及到近似搜索或者拼音匹配等技术...

    一个专业搜索公司关于lucene+solar资料(1)

    - 索引结构包括倒排索引等,能够高效地处理大量文本数据。 - **2.2.3 Lucene全文检索引擎** - Lucene是Apache基金会的一个开源项目,提供了强大的文本搜索能力。 - 可以轻松集成到任何应用中,提供高级的搜索...

    C#垂直搜索网站代码下载

    2. **索引构建**:构建倒排索引,这是一种用于快速定位文档中包含特定词的位置的数据结构,是搜索引擎的核心部分。 3. **查询解析**:将用户输入的查询字符串转化为可执行的搜索表达式,可能涉及到同义词扩展、短语...

    通用大数据存储与分析处理平台_Hadoop.docx

    最后,文档探讨了海量数据处理的思路,包括Bloom filter、Hashing、bit-map、堆、双层桶划分、数据库索引(如倒排索引)和外排序等方法,并引用了关于Hadoop框架和MapReduce模式的经典文章,帮助读者深入理解海量...

    Java进阶路线

    - **倒排索引**:一种高效的数据结构,用于快速查找文档集合中包含特定关键词的所有文档。 - **Lucene, ElasticSearch, Solr, ELK**:流行的企业级搜索解决方案。 - **准确性, 召回率, 实时性**:评估搜索质量的关键...

    Hbase官方文档

    - 通过分区表、倒排索引等方式支持更复杂的查询需求。 #### 六、HBase与MapReduce集成 **7.1 Map-Task Spitting** - 在MapReduce作业中根据Row Key范围自动划分Map任务。 **7.2 HBase MapReduce Examples** - ...

Global site tag (gtag.js) - Google Analytics