Exemple #1
0
        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}");
        }