static void Main(string[] args) { string path = "../../../../../"; Console.WriteLine("Start Task14_FullTextSearch"); var reader = new StreamReader(path + "Resources/zaliznyak_shortform.txt"); Dictionary <string, string> normal_form = new Dictionary <string, string>(); string line = null; string normal = null; int cnt = 0; while ((line = reader.ReadLine()) != null) { string[] prts = line.Split(' '); normal = prts[0]; foreach (string w in prts) { normal_form.TryAdd(w, normal); } cnt++; } Console.WriteLine($"n={cnt} words={normal_form.Count}"); PType tp_elem = new PTypeRecord( new NamedType("nom", new PType(PTypeEnumeration.integer)), new NamedType("news", new PType(PTypeEnumeration.sstring))); int dnom = 0; Func <Stream> getStream = () => File.Open(path + "Databases/data" + (dnom++), FileMode.OpenOrCreate); TableSimple table = new TableSimple(tp_elem, new int[] { 0 }, getStream); table.Fill(Generate(path + "Resources/academpark-newsflow.txt")); // Построение полнотекстового индекса PType tp_index = new PTypeRecord( new NamedType("nom", new PType(PTypeEnumeration.integer)), new NamedType("word", new PType(PTypeEnumeration.sstring))); TableSimple ft_index = new TableSimple(tp_index, new int[] { 1 }, getStream); char[] delems = new char[] { ' ', ',', '.', '!', '?', '\n', '-', ':' }; //Func<object[]> generateNomWordFlow = () => var generateNomWordFlow = table.ElementValues() .SelectMany(nomtext => { int nom = (int)nomtext[0]; string text = (string)nomtext[1]; string[] words = text.Split(delems); var setofwords = words.Where(w => !string.IsNullOrEmpty(w) && w.Length > 2 && char.IsLetter(w[0])) .Select(w => { if (normal_form.TryGetValue(w.ToLower(), out string wrd)) { return(wrd); } return(null); }) .Where(w => !string.IsNullOrEmpty(w)) .Distinct(); return(setofwords.Select(w => new object[] { nom, w })); }); // Заполнение таблицы ft_index.Fill(generateNomWordFlow); // Поиск по одному слову var qu = ft_index.GetAllByKey(1, "олимпиада"); foreach (object[] vv in qu) { int nom = (int)vv[0]; var qq = table.GetAllByKey(0, nom).FirstOrDefault(); Console.WriteLine($"{qq[0]} {qq[1]}"); } // Тестирование скорости System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); string aaa = "Завтра в Академпарке назовут новых резидентов бизнес инкубаторов 5 марта состоится торжественная церемония закрытия десятой юбилейной инновационной школы Академпарка Начало подведения итогов"; string[] parts = aaa.ToLower().Split(' '); Console.WriteLine(parts.Count() + " samples"); int cont = 0; sw.Start(); foreach (string w in parts) { cont += ft_index.GetAllByKey(1, w).Select((object[] vv) => { int nom = (int)vv[0]; return(table.GetAllByKey(0, nom).FirstOrDefault()); }).Count(); } sw.Stop(); Console.WriteLine($"всего найдено документов: {cont} за время: {sw.ElapsedMilliseconds}"); }
static void Main(string[] args) { Console.WriteLine("Start Task13_TripleStore"); // Создаем генератор триплетов теста фототека. Генерируем поток массивов трех строк. Входным параметром является количество персон Random rnd = new Random(); Func <int, IEnumerable <string[]> > GenerateTriples = n => { // n персон var persons = Enumerable.Range(0, n).SelectMany(i => new string[][] { new string[] { "<p" + (n - i - 1) + ">", "<name>", "Pupkin_" + (n - i - 1) }, // имя new string[] { "<p" + (n - i - 1) + ">", "<age>", "33" } // возраст }); // 2*n фоток var photos = Enumerable.Range(0, 2 * n).SelectMany(i => new string[][] { new string[] { "<ph" + (2 * n - i - 1) + ">", "<name>", "DSP_" + (2 * n - i - 1) }, // имя new string[] { "<ph" + (2 * n - i - 1) + ">", "<age>", "33" } // возраст }); // 6*n отражений var reflections = Enumerable.Range(0, 6 * n).SelectMany(i => new string[][] { new string[] { "<re" + (6 * n - i - 1) + ">", "<reflected>", "<p" + rnd.Next(n) + ">" }, // отражаемое new string[] { "<re" + (6 * n - i - 1) + ">", "<inphoto>", "<ph" + rnd.Next(2 * n) + ">" } // в документе }); return(persons.Concat(photos).Concat(reflections)); }; PType tp_triple = new PTypeRecord( new NamedType("subject", new PType(PTypeEnumeration.sstring)), new NamedType("predicate", new PType(PTypeEnumeration.sstring)), new NamedType("object", new PType(PTypeEnumeration.sstring))); string path = "data"; int nom = 0; TableSimple triples = new TableSimple(tp_triple, new int[] { 0, 2 }, () => File.Open(path + (nom++), FileMode.OpenOrCreate)); int npersons = 400_000; bool toload = true; if (toload) // Загрузка данных { triples.Fill(GenerateTriples(npersons)); } string sample = "<p" + (npersons * 2 / 3) + ">"; var rfls = triples.GetAllByKey(2, sample).Where(r => (string)r[1] == "<reflected>"); foreach (object[] r in rfls) { Console.WriteLine($"{r[0]} {r[1]} {r[2]}"); } Console.WriteLine(); var indocs = rfls.SelectMany(r => triples.GetAllByKey(0, r[0])).Where(t => (string)t[1] == "<inphoto>"); foreach (object[] r in indocs) { Console.WriteLine($"{r[0]} {r[1]} {r[2]}"); } Console.WriteLine(); var phs = indocs.SelectMany(r => triples.GetAllByKey(0, r[2])).Where(t => (string)t[1] == "<name>"); foreach (object[] r in phs) { Console.WriteLine($"{r[0]} {r[1]} {r[2]}"); } Console.WriteLine(); // Теперь цикл по образцам System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); int nsamples = 1000; sw.Start(); int count = 0; for (int i = 0; i < nsamples; i++) { sample = "<p" + rnd.Next(npersons) + ">"; var que = triples.GetAllByKey(2, sample).Where(r => (string)r[1] == "<reflected>") .SelectMany(r => triples.GetAllByKey(0, r[0])).Where(t => (string)t[1] == "<inphoto>") .SelectMany(r => triples.GetAllByKey(0, r[2])).Where(t => (string)t[1] == "<name>"); //foreach (object[] r in que) Console.WriteLine($"{r[0]} {r[1]} {r[2]}"); //Console.WriteLine(); count += que.Count(); } sw.Stop(); Console.WriteLine($"count={count} duration={sw.ElapsedMilliseconds}"); }