获得完全匹配的结果

时间:2015-02-24 13:23:43

标签: lucene hibernate-search

我想在“水果”字段上进行类似的查询:“香蕉苹果樱桃”。

甜点中的所有水果都需要在查询中,但查询中的所有水果都不需要在甜点中。

这是一个例子..

NAME FRUIT

Dessert1香蕉苹果OK(我们在查询中得到了香蕉和苹果)

甜点2樱桃苹果香蕉OK(顺序无所谓)

Dessert3樱桃苹果香蕉瓜NO(查询中缺少甜瓜)

public class ArrayStringFieldBridge implements TwoWayFieldBridge{


@Override
public Object get(String name, Document document) {
    IndexableField[] fields = document.getFields(name);
    String[] values = new String[fields.length];
    for (int i=0; i<fields.length; i++) {
        values[i] = fields[i].stringValue();
    }
    return values;
}

@Override
public String objectToString(Object value) {
    return StringUtils.join((String[])value, " ");
}

@Override
public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
    String newString = StringUtils.join((String[])value, " ");
    Field field = new Field(name, newString, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector());
    field.setBoost(luceneOptions.getBoost());
    document.add(field);
}

}

@Indexed
@AnalyzerDef(name = "customanalyzer",
    tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class))
public class Dessert {

    @Analyzer(definition="customanalyzer")
    @Field(name = "equipment", index=Index.YES, analyze = Analyze.YES, store=Store.YES)
    @FieldBridge(impl=ArrayStringFieldBridge.class)
    public String[] fruits = new String[]{};
}

即使你没有使用hibernate-search,关于理论的每一个建议都会很好......谢谢你

1 个答案:

答案 0 :(得分:1)

步骤1:消防lucene查询“水果:香蕉或水果:苹果或水果:樱桃”

第2步:收集所有匹配的甜点文件

第3步:使用查询后处理您的匹配甜点文档

  • 将匹配文档转换为匹配数组matchDocArr:{banana,apple}
  • 将查询字词转换为数组 - queryArr:{banana,apple,cherry}
  • 迭代matchDocArr并确保在queryArr中通过数组找到matchDocArr的每个术语,如果NOT(甜瓜用例)敲除此匹配文档

以下是需要为每个匹配的文档调用的示例函数

public static boolean isDocInterested(String query, String matchDoc)
{
    List<String> matchDocArr = new ArrayList<String>();
    matchDocArr = Arrays.asList(matchDoc.split(" "));

    List<String> queryArr = new ArrayList<String>();
    queryArr = Arrays.asList(query.split(" "));

    int matchCounter = 0;
    for(int i=0; i<matchDocArr.size(); i++)
    {
        if (queryArr.contains(matchDocArr.get(i)))
            matchCounter++;
    }

    if (matchCounter == matchDocArr.size())
        return true;

    return false;
}

如果函数返回TRUE,我们对doc / dessert感兴趣,如果返回FALSE则忽略此doc /甜点。

当然这个函数可以用很多不同的方式编写,但我认为你明白了。