2009-10-17 3 views
2

Как я могу получить количество экземпляров в Word в текстовом поле базы данных С LINQ?Подсчет слов в текстовом поле с помощью LINQ

Ключевое слово лексема образец: ASP.NET

EDIT 4:

базы данных записей:

Запись 1: [TextField] = «Бла-бла-бла ASP.NET бли бли бли ASP .NET голуб ASP.NET Yop Yop ASP.NET "

Запись 2: [TextField] = "бла BLI BLI BLI голуб ASP.NET Yop Yop ASP.NET"

Запись 3: [TextField] = «Бла ASP.NET бла ASP .NET ли ASP.NET л ASP.NET ли ли ASP.NET голубов ASP.NET Yop Yop ASP.NET "

Так

Запись 1 Содержит 4 возникновение "ASP.NET" ключевое слово

Запись 2 содержит 2 возникновение "ASP.NET" ключевое слово

Запись 3 Содержит 7 возникновение "ASP.NET" ключевое слово

Коллекция Extraction IList < RecordModel> (отсортированы по количеству слов по убыванию)

  • Запись 3
  • Запись 1
  • Запись 2

LinqToSql должен быть лучшим, но LinqToObject тоже :)

NB: Не вопрос о "" из ASP.NET ключевого слова (это не цель, если этот вопрос)

+0

Вы пытаетесь сделать это на стороне базы данных, используя Linq to SQL? Или вы работаете с подмножеством данных на стороне клиента (то есть Linq для объектов над коллекцией)? –

+0

Я уже выбрал подмножество данных, содержащих ключевые слова. Итак, теперь я работаю в Linq To Object over collection yep :) –

+0

Но я думаю, что лучше всего построить все в одном запросе LinqToSQL для производительности, возможно ... Вместо предварительной выборки данных, содержащих все ключевые слова а затем выполнить эту операцию в памяти? –

ответ

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); 
} 

Voila! :)

0

Вы можете Regex.Matches(input, pattern).Count или вы могли бы сделать следующее:

int count = 0; int startIndex = input.IndexOf(word); 
while (startIndex != -1) { ++count; startIndex = input.IndexOf(word, startIndex + 1); } 

с помощью LINQ здесь будет некрасиво

1

Использование String.split(), чтобы превратить строку в массив слов, а затем использовать LINQ для фильтрации списка возвращающегося только те слова, которые вы хотите, а затем проверить подсчет результата, как это:

myDbText.Split(' ').Where(token => token.Equals(word)).Count(); 
+0

Слово может сопровождаться периодом или иметь заглавную букву. –

4

Edit 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»). Я исключил это из списка разделителей, к сожалению, что будет загрязнять некоторые слова в качестве предложения типа «Бла-бла-бла-бла-бла-бла». будет показывать «бла» со счетом 3 и «бла». со счетом 2. Вам нужно подумать о том, какую стратегию очистки вы хотите здесь, например. если "." имеет букву с обеих сторон, она считается частью слова, иначе это пробел. Такая логика лучше всего делать с некоторыми RegEx.

+0

Что делать, если слово есть, а у вас его нет в тексте? Это будет зависеть от требований, если ваше решение будет работать. –

+0

Мне действительно не нужно подсчитывать определенное слово, но извлечение данных, упорядоченное по максимальному счету определенного количества слов, основанному на каждой записи –

+0

Те же проблемы с [.] Также применимы к ['], если вы хотите чтобы исключить кавычки, за исключением случаев, когда они являются частью слова. Эта проблема, вероятно, лучше всего разделить на другой вопрос, так как вам нужно, чтобы лучшее регулярное выражение извлекало слова (если на этот вопрос уже нет ответа). –

0

Я знаю, что это больше, чем исходный вопрос, но он по-прежнему соответствует теме, и я включаю его для других, которые ищут по этому вопросу позже. Это не требует, чтобы все слова были сопоставлены в искомых строках, однако его можно легко модифицировать с помощью кода из сообщения Ахмада.

//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; } 
} 

.