如何在vespa中进行预先搜索?

问题描述 投票:2回答:1

我正在尝试使用vespa构建先行搜索。由于有很多数据,我不想使用流模式。通配符搜索是我期望看到的,但它看起来仅限于流模式(正则表达式和匹配:子字符串仅适用于流模式)。任何关于如何实现它或定制的指针将不胜感激。

vespa
1个回答
3
投票

我看到应用程序为此做的如下:

  1. 将所有文本放在属性数组中并在该数组上设置快速搜索。这为您提供了一致的非常低的延迟,因为您只能访问内存,并且能够使用前缀匹配。它会禁用全文相关性,但您不需要这样做。
  2. 使用前缀匹配,而不是子串。如果要按前缀匹配所有术语,只需在搜索定义中的字段上设置match:前缀即可。它可以提供更好的用户体验,但仅对前一个术语进行前缀匹配。在这种情况下,保持默认匹配并重写查询(在搜索器中)以生成最后一个WordItem和PrefixItem。

例如,您可以在搜索定义中定义字段,如下所示:

field suggestions type array<string> {
    indexing: input myinputtextfield |split "\\s+" | summary | attribute
    attribute: fast-search
}

要在最后一个术语上进行前缀匹配,添加一个Searcher component,其执行以下操作:

import com.yahoo.prelude.query.CompositeItem;
import com.yahoo.prelude.query.Item;
import com.yahoo.prelude.query.PrefixItem;
import com.yahoo.prelude.query.WordItem;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.Searcher;
import com.yahoo.search.query.QueryTree;
import com.yahoo.search.searchchain.Execution;

import java.util.ListIterator;

public class PrefixMatchSearcher extends Searcher {

    @Override
    public Result search(Query query, Execution execution) {
        matchLastByPrefix(query);
        return execution.search(query);
    }

    private boolean matchLastByPrefix(Query query) {
        boolean spaceTerminated = query.getModel().getQueryString().endsWith(" ");
        if (spaceTerminated) return false;

        QueryTree tree = query.getModel().getQueryTree();
        if (tree.getRoot() instanceof WordItem) {
            tree.setRoot(toPrefixItem((WordItem) tree.getRoot()));
            return true;
        }
        else if (tree.getRoot() instanceof CompositeItem) {
            CompositeItem root = (CompositeItem) tree.getRoot();
            for (ListIterator<Item> i = root.getItemIterator(); i.hasNext();) {
                Item child = i.next();
                if (i.hasNext()) continue; // Skip to last

                if (child instanceof WordItem) { 
                    i.set(toPrefixItem((WordItem)child));
                    return true;
                }
            }
        }
        return false;
    }

    private PrefixItem toPrefixItem(WordItem word) {
        return new PrefixItem(word.getWord(), word.getIndexName());
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.