2

私は特別な名前を含む検索インデックスを構築しています-含む!と ?と&と+と...私は次の検索を別の方法で踏まなければなりません:

私とあなた

私+あなた

しかし、私が何をしても(インデックス作成の前にクエリパーサーをエスケープしてみました、手動でエスケープし、別のインデクサーを試しました...)-Lukeで検索インデックスをチェックすると、それらは表示されません(疑問符や@記号などが表示されます) )。

背後にあるロジックは、ライブの提案を部分的に検索しているため(フィールドはそれほど大きくない)、「m」と「me」と「+」と「y」と「yo」と「次に、インデックスを作成します(これにより、ワイルドカードクエリ検索よりもはるかに高速になります(インデックスのサイズは大きな問題ではありません)。

したがって、必要なのは、この特別なワイルドカード文字もインデックスに挿入することです。

これは私のコードです:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Lucene.Net.Analysis;
using Lucene.Net.Util;

namespace AnalyzerSpike
{
    public class CustomAnalyzer : Analyzer
    {
        public override TokenStream TokenStream(string fieldName, TextReader reader)
        {
            return new ASCIIFoldingFilter(new LowerCaseFilter(new CustomCharTokenizer(reader)));
        }
    }

    public class CustomCharTokenizer : CharTokenizer
    {
        public CustomCharTokenizer(TextReader input) : base(input)
        {

        }

        public CustomCharTokenizer(AttributeSource source, TextReader input) : base(source, input)
        {
        }

        public CustomCharTokenizer(AttributeFactory factory, TextReader input) : base(factory, input)
        {
        }

        protected override bool IsTokenChar(char c)
        {
            return c != ' ';
        }
    }
}

インデックスを作成するためのコード:

private void InitIndex(string path, Analyzer analyzer)
{
    var writer = new IndexWriter(path, analyzer, true);

    //some multiline textbox that contains one item per line:
    var all = new List<string>(txtAllAvailable.Text.Replace("\r","").Split('\n'));

    foreach (var item in all)
    {
        writer.AddDocument(GetDocument(item));
    }

    writer.Optimize();
    writer.Close();
}

private static Document GetDocument(string name)
{
    var doc = new Document();

    doc.Add(new Field(
        "name",
        DeNormalizeName(name),
        Field.Store.YES,
        Field.Index.ANALYZED));

    doc.Add(new Field(
                "raw_name",
                name,
                Field.Store.YES,
                Field.Index.NOT_ANALYZED));

    return doc;
}

(コードはバージョン1.9.xのLucene.netにあります(編集:申し訳ありませんが-2.9.xでした)が、JavaのLuceneと互換性があります)

どうも

4

1 に答える 1

0

ついにそれをもう一度調べる時間がありました。そして、(最初のように)単一の文字部分を除外したのは私の非正規法のいくつかの愚かな間違いでした。したがって、スペースで囲まれている場合はプラス記号を除外しました:-/

Moleskiを通してあなたの助けをありがとう!

private static string DeNormalizeName(string name)
{
    string answer = string.Empty;

    var wordsOnly = Regex.Replace(name, "[^\\w0-9 ]+", string.Empty);
    var filterText = (name != wordsOnly) ? name + " " + wordsOnly : name;

    foreach (var subName in filterText.Split(' '))
    {
        if (subName.Length >= 1)
        {
            for (var j = 1; j <= subName.Length; j++)
            {
                answer += subName.Substring(0, j) + " ";
            }
        }
    }
    return answer.TrimEnd();
}
于 2010-03-16T14:00:20.827 に答える