Search Lucene层次分类搜索

Search Lucene层次分类搜索,search,lucene,taxonomy,Search,Lucene,Taxonomy,我有一组用层次分类标记注释的文档, 例如 我需要按“图书类别”搜索图书。搜索必须返回完全或部分匹配查询类别(具有定义的深度阈值)的书籍,并根据匹配程度为它们提供不同的分数 例如:查询“图书类别=/小说/喜剧”和“深度阈值=1”必须返回图书类别=/小说/喜剧(分数=100%)、小说和/小说/喜剧/新(分数

我有一组用层次分类标记注释的文档, 例如

我需要按“图书类别”搜索图书。搜索必须返回完全或部分匹配查询类别(具有定义的深度阈值)的书籍,并根据匹配程度为它们提供不同的分数

例如:查询“图书类别=/小说/喜剧”和“深度阈值=1”必须返回图书类别=/小说/喜剧(分数=100%)、小说和/小说/喜剧/新(分数<100%)的图书

我在搜索中尝试了TopScoreDocCollector,但它返回了至少包含查询类别的book_类别,并给出了相同的分数

我如何获得这个搜索函数,它还返回更一般的类别,并为结果提供不同的匹配分数

附言:我不需要面对面的搜索


谢谢

没有支持此重新查询的内置查询,但是您可以将
析取MaxQuery
与多个
ConstantCoreQuery
一起使用。可以通过simple
TermQuery
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.