2

LINQを使用してデータベーステキストフィールドの単語の出現回数を取得するにはどうすればよいですか?

キーワードトークンサンプル:ASP.NET

編集4:

データベースレコード:

レコード1:[TextField] = "Blah blah blah ASP.NET bli bli bli ASP.NET blu ASP.NET yop yop ASP.NET "

レコード2:[TextField] = "Blah blah blah bli bli bli blu ASP.NET yop yop ASP.NET "

レコード3:[TextField] = "Blah ASP.NET blah ASP.NET blah ASP.NET bli ASP.NET bli bli ASP.NET blu ASP.NET yop yop ASP.NET "

それで

レコード1には「ASP.NET」キーワードが4つ含まれています

レコード2には「ASP.NET」キーワードが2つ含まれています

レコード3には「ASP.NET」キーワードが7つ含まれています

コレクション抽出IList<RecordModel>(単語数の降順)

  • レコード3
  • レコード1
  • レコード2

LinqToSQLが最適なはずですが、LinqToObjectも:)

注意:「。」については問題ありません。ASP.NETキーワードの(この質問の場合、これは目標ではありません)

4

5 に答える 5

4

編集 2: 質問を更新し、少し変更し、単語ごとの単語数を変更したようです。これを試して:

string input = "some random text: how many times does each word appear in some random text, or not so random in this case";
char[] separators = new char[]{ ' ', ',', ':', ';', '?', '!', '\n', '\r', '\t' };

var query = from s in input.Split( separators )
            where s.Length > 0
            group s by s into g
            let count = g.Count()
            orderby count descending
            select new {
                Word = g.Key,
                Count = count
            };

「。」を含む可能性のある単語が必要なので。それら (例: "ASP.NET") を区切りリストから除外しましたが、残念ながら、"Blah blah blah. Blah blah." のような文としていくつかの単語を汚してしまいます。カウントが 3 の "blah" と "blah" が表示されます。ここで必要なクリーニング戦略を考える必要があります。たとえば、「。」両側に文字があり、単語の一部としてカウントされます。それ以外の場合は空白です。この種のロジックは、いくつかの RegEx で行うのが最適です。

于 2009-10-17T16:50:53.163 に答える
3

正規表現はこれをうまく処理します。メタ文字を使用し\bて単語の境界を固定し、キーワードをエスケープして、特殊な正規表現文字の意図しない使用を避けることができます。また、末尾のピリオド、コンマなどのケースも処理します。

string[] records =
{
    "foo ASP.NET bar", "foo bar",
    "foo ASP.NET? bar ASP.NET",
    "ASP.NET foo ASP.NET! bar ASP.NET",
    "ASP.NET, ASP.NET ASP.NET, ASP.NET"
};
string keyword = "ASP.NET";
string pattern = @"\b" + Regex.Escape(keyword) + @"\b";
var query = records.Select((t, i) => new
            {
                Index = i,
                Text = t,
                Count = Regex.Matches(t, pattern).Count
            })
            .OrderByDescending(item => item.Count);

foreach (var item in query)
{
    Console.WriteLine("Record {0}: {1} occurrences - {2}",
        item.Index, item.Count, item.Text);
}

出来上がり!:)

于 2009-10-17T17:51:26.100 に答える
1

String.Split() を使用して文字列を単語の配列に変換し、LINQ を使用してこのリストをフィルター処理し、必要な単語のみを返します。次に、次のように結果の数を確認します。

myDbText.Split(' ').Where(token => token.Equals(word)).Count();
于 2009-10-17T16:44:47.560 に答える
0

これは元の質問よりも多いことはわかっていますが、それでも件名と一致するため、後でこの質問を検索する他の人のために含めています. これは、検索される文字列で単語全体が一致する必要はありませんが、Ahmad の投稿のコードを使用して簡単に変更できます。

//use this method to order objects and keep the existing type
class Program
{
  static void Main(string[] args)
  {
    List<TwoFields> tfList = new List<TwoFields>();
    tfList.Add(new TwoFields { one = "foo ASP.NET barfoo bar", two = "bar" });
    tfList.Add(new TwoFields { one = "foo bar foo", two = "bar" });
    tfList.Add(new TwoFields { one = "", two = "barbarbarbarbar" });

    string keyword = "bar";
    string pattern = Regex.Escape(keyword);
    tfList = tfList.OrderByDescending(t => Regex.Matches(string.Format("{0}{1}", t.one, t.two), pattern).Count).ToList();

    foreach (TwoFields tf in tfList)
    {
      Console.WriteLine(string.Format("{0} : {1}", tf.one, tf.two));
    }

    Console.Read();
  }
}


//a class with two string fields to be searched on
public class TwoFields
{
  public string one { get; set; }
  public string two { get; set; }
}

.

//same as above, but uses multiple keywords
class Program
{
  static void Main(string[] args)
  {
    List<TwoFields> tfList = new List<TwoFields>();
    tfList.Add(new TwoFields { one = "one one, two; three four five", two = "bar" });
    tfList.Add(new TwoFields { one = "one one two three", two = "bar" });
    tfList.Add(new TwoFields { one = "one two three four five five", two = "bar" });

    string keywords = " five one    ";
    string keywordsClean = Regex.Replace(keywords, @"\s+", " ").Trim(); //replace multiple spaces with one space

    string pattern = Regex.Escape(keywordsClean).Replace("\\ ","|"); //escape special chars and replace spaces with "or"
    tfList = tfList.OrderByDescending(t => Regex.Matches(string.Format("{0}{1}", t.one, t.two), pattern).Count).ToList();

    foreach (TwoFields tf in tfList)
    {
      Console.WriteLine(string.Format("{0} : {1}", tf.one, tf.two));
    }

    Console.Read();
  }
}

public class TwoFields
{
  public string one { get; set; }
  public string two { get; set; }
}
于 2010-08-04T21:26:41.837 に答える