Lucene字段名通配符特性及type为AX1的分类查询方案问询
解决方案:Lucene查询type为AX1的category并获取条目ID
问题核心
Lucene的标准QueryParser语法不支持字段名中间的通配符(如data.id.*.category.id.*.type这种写法),这是你原查询失效的原因。以下是两种可行的解决思路:
一、最优方案:重构文档扁平化逻辑
当前嵌套式的字段命名(如data.id.01.category.id.100.type)既不便于查询,也会增加存储和检索开销。建议调整扁平化规则,将关联数据拆分为独立的多值字段:
重构后的文档结构示例
-- Document -- : Field : data_id , Value : 01 Field : name , Value : Test1 Field : category_id , Value : 100 Field : category_type , Value : AX1 Field : category_id , Value : 101 Field : category_type , Value : AX2
每个category条目对应的data_id、category_id、category_type作为多值字段存储,关联关系通过字段的多值顺序保持(或直接为每个category生成独立文档,视业务需求而定)。
查询语句
直接通过明确的字段查询,高效获取匹配结果:
category_type:AX1
查询后即可从匹配文档中提取对应的data_id(上层条目ID)和category_id(分类ID)。
二、临时方案:通过API构造字段通配符查询(不推荐)
如果无法修改现有文档结构,可通过Lucene API手动构建字段名的通配符查询(性能较差,仅作为临时替代):
Java API示例
// 构造匹配所有以".type"结尾的字段、值为AX1的查询 WildcardQuery typeQuery = new WildcardQuery(new Term("*.type", "AX1")); // 执行查询后,遍历结果文档,解析字段名获取关联ID for (ScoreDoc scoreDoc : searcher.search(typeQuery, 100).scoreDocs) { Document doc = searcher.doc(scoreDoc.doc); for (IndexableField field : doc.getFields()) { String fieldName = field.name(); if (fieldName.endsWith(".type") && field.stringValue().equals("AX1")) { // 从字段名解析出data.id和category.id // 示例:fieldName = "data.id.01.category.id.100.type" String[] parts = fieldName.split("\\."); String dataId = parts[2]; String categoryId = parts[5]; // 处理获取到的ID } } }
若使用QueryParser(需开启字段通配符支持)
部分Lucene版本可通过配置允许字段名通配符,注意这会带来性能风险:
QueryParser parser = new QueryParser("default_field", new StandardAnalyzer()); parser.setAllowLeadingWildcard(true); // 允许字段名使用前缀通配符 Query query = parser.parse("*.type:AX1");
内容的提问来源于stack exchange,提问作者Devidas Yadav
相关产品推荐
相关产品推荐

