Search Lucene层次分类搜索
我有一组用层次分类标记注释的文档, 例如 我需要按“图书类别”搜索图书。搜索必须返回完全或部分匹配查询类别(具有定义的深度阈值)的书籍,并根据匹配程度为它们提供不同的分数 例如:查询“图书类别=/小说/喜剧”和“深度阈值=1”必须返回图书类别=/小说/喜剧(分数=100%)、小说和/小说/喜剧/新(分数<100%)的图书 我在搜索中尝试了TopScoreDocCollector,但它返回了至少包含查询类别的book_类别,并给出了相同的分数 我如何获得这个搜索函数,它还返回更一般的类别,并为结果提供不同的匹配分数 附言:我不需要面对面的搜索Search Lucene层次分类搜索,search,lucene,taxonomy,Search,Lucene,Taxonomy,我有一组用层次分类标记注释的文档, 例如 我需要按“图书类别”搜索图书。搜索必须返回完全或部分匹配查询类别(具有定义的深度阈值)的书籍,并根据匹配程度为它们提供不同的分数 例如:查询“图书类别=/小说/喜剧”和“深度阈值=1”必须返回图书类别=/小说/喜剧(分数=100%)、小说和/小说/喜剧/新(分数
谢谢没有支持此重新查询的内置查询,但是您可以将
析取MaxQuery
与多个ConstantCoreQuery
一起使用。可以通过simpleTermQuery
s搜索确切类别和更一般的类别。对于子类别,如果您事先不知道所有子类别,则可以使用多术语查询
,如RegexpQuery
,来匹配所有子类别。例如:
// the exact category
Query directQuery = new TermQuery(new Term("book_category", "/novel/comedy"));
// regex, that matches one level more that your exact category
Query narrowerQuery = new RegexpQuery(new Term("book_category", "/novel/comedy/[^/]+"));
// the more general category
Query broaderQuery = new TermQuery(new Term("book_category", "/novel"));
directQuery = new ConstantScoreQuery(directQuery);
narrowerQuery = new ConstantScoreQuery(narrowerQuery);
broaderQuery = new ConstantScoreQuery(broaderQuery);
// 100% for the exact category
directQuery.setBoost(1.0F);
// 80% for the more specific category
narrowerQuery.setBoost(0.8F);
// 50% for the more general category
broaderQuery.setBoost(0.5F);
DisjunctionMaxQuery query = new DisjunctionMaxQuery(0.0F);
query.add(directQuery);
query.add(narrowerQuery);
query.add(broaderQuery);
这将产生如下结果:
id=3 title=a hilarious book book_category=/novel/comedy score=1.000000
id=1 title=a funny book book_category=/novel/comedy/new score=0.800000
id=5 title=A very sad story book_category=/novel score=0.500000
有关完整的测试用例,请参见以下要点:这可以通过解决方案实现。但我要查询的层次结构字段不止一个,我想使用分类法中索引的CategoryPath。 我正在使用向下展开查询:
DrillDownQuery luceneQuery = new DrillDownQuery(searchParams.indexingParams);
luceneQuery.add(new CategoryPath("book_category/novel/comedy,'/'));
luceneQuery.add(new CategoryPath("subject/sub1/sub2",'/'));
通过这种方式,搜索将返回图书如何匹配两个类别路径及其后代。
为了检索祖先,我可以从请求的categoryPath(从分类法检索)的祖先开始向下搜索
问题是所有结果的分数相同。
我想覆盖相似度/分数函数,以便计算基于categoryPath长度的分数,将查询categoryPath与每个返回的文档categoryPath(book_category)进行比较
例如:
if(queryCategoryPath.compareTo(bookCategoryPath)==0){
document.score = 1
}else if(queryCategoryPath.compareTo(bookCategoryPath)==1){
document.score = 0.9
}else if(queryCategoryPath.compareTo(bookCategoryPath)==2){
document.score = 0.8
} and so on.
在您的示例中,搜索结果不应包含具有/novel/dramma的书籍?是的,仅包含与查询完全匹配的类别的书籍,或包含根据深度更一般或更具体的类别的书籍。感谢您的回答,但我认为这是一个静态解决方案,由正则表达式驱动。这样,我就失去了分类层次结构,无法静态地设置查询。有一种方法可以使用分类法吗?也许可以将类别查询标识为分类法中的一个节点,获取我需要的祖先和后代,并使用它们创建具有相关boost的查询。通过分类法,您是否参考lucenes包?如果是这样,这将不符合您的要求。
/novel/traic
类别将被索引为/novel
和/novel/traic
,对更一般类别的查询将匹配所有文档。这里的正则表达式只匹配一个以上的级别,但是如果您预先知道您的分类法,您可以创建任意多个具体的TermQuery
s
if(queryCategoryPath.compareTo(bookCategoryPath)==0){
document.score = 1
}else if(queryCategoryPath.compareTo(bookCategoryPath)==1){
document.score = 0.9
}else if(queryCategoryPath.compareTo(bookCategoryPath)==2){
document.score = 0.8
} and so on.