Рисунок 3.3. Добавление документа в документо-ориентированную базу данных
Также при добавлении, удалении или изменении текста документа происходит соответствующее изменение данных в структуре для индексации на основе естественно-языковой адресации.
3.2 Реализация индексации на основе естественно-языковой адресации
Была реализована многомерная древовидная структура в виде многоуровневой хеш-таблицы на основе стандартного класса Dictionary<Tkey, TValue>. Ключом была выбрана подстрока из трех символов. Так как обработка текста и структуры индексов занимает достаточно большое время, данные операции проводятся в отдельных потоках, завершение которых необязательно для завершения метода.
При добавлении нового документа его плоский текст обрабатывается следующим образом для добавления ключевых слов в структуру для индексации на основе естественно-языковой адресации:
1. Очищение текста от знаков препинания и стоп-слов.
2. Стемминг - выделение основ ключевых слов при помощи дополнительной библиотеки.
3. Добавление основы каждого ключевого слова в структуру индексации.
При добавлении в структуру производятся следующие действия:
1. Загружается из документо-ориентированной базы данных файл с соответствующим корнем дерева и десериализуется.
2. Для каждой трехбуквенной (последняя может быть меньше) подстроки с начала слова:
2.1. Получается объект IndexStructureObject по данной подстроке-ключу в текущей структуре.
2.2. Если это последняя подстрока, то идентификатор документа добавляется к списку идентификаторов.
2.3. Иначе загружается или создается структура следующего уровня для данной подстроки, она становится текущей.
2.4. Изменения сохраняются.
При удалении идентификатора документа из структуры происходит обход дерева в глубину (так как вложенность не слишком высока), и все вхождения данного идентификатора удаляются.
3.3 Публикация сервиса
Для работы сервиса на портале Azure были созданы базы данных: реляционная SQL Azure и документо-ориентированная Cosmos DB. Таблицы реляционной СУБД создавались с помощью Entity Framework. В документо-ориентированной Cosmos DB были созданы две коллекции: для документов и для сериализованной структуры для индексации на основе естественно-языковой адресации. Далее с помощью предоставляемого Azure профиля публикации веб-приложения и встроенных средств Visual Studio сервис опубликован и доступен по ссылке: https://papercatdatastorage.azurewebsites.net/CorporaStorageService.svc.
Рисунок 3.4. Опубликованный сервис
Таким образом, сервис доступен по сети Интернет и может быть использован разными видами клиентов, все данные при этом хранятся в облачном хранилище портала Azure.
Глава 4. Тестирование
В ходе работы необходимо протестировать не только реализацию всех функций сервиса для хранения корпусов, но и возможность взаимодействие этого сервиса с другими компонентами системы. Также необходимо исследовать полезность применения индексации на основе естественно-языковой адресации.
4.1 Функциональное тестирование
На этапе функционального тестирования проводилось тестирование основных функций сервиса по методу черного ящика:
1. Добавление нового пользователя.
Результаты тестирования добавления информации о пользователе представлены в таблице Таблица 4.1.
Таблица 4.1. Тестирование добавления информации о пользователе
|
№ |
Входные данные |
Ожидаемый результат |
Реальный результат |
|
|
1 |
null |
Ошибка «Параметр не может быть null» |
Ошибка «Параметр не может быть null» |
|
|
2 |
User{ FIO = “Фамилия Имя Отчество”, Email = “email@email.com”, Login = “Login”, Password = “Password”} |
В базу данных добавлена информация о пользователе с FIO = “Фамилия Имя Отчество”, Email = “email@email.com”, Login = “Login”, Password = “Password”. UserId сгенерирован |
В базу данных добавлена информация о пользователе с FIO = “Фамилия Имя Отчество”, Email = “email@email.com”, Login = “Login”, Password = “Password”. UserId сгенерирован (1) |
|
|
3 |
User{UserId = 0, FIO = “Фамилия Имя Отчество”, Email = “email@email.com”, Login = “Login3”, Password = “Password3”} |
В базу данных добавлена информация о пользователе с FIO = “Фамилия Имя Отчество”, Email = “email@email.com”, Login = “Login3”, Password = “Password3”. UserId сгенерирован |
В базу данных добавлена информация о пользователе с FIO = “Фамилия Имя Отчество”, Email = “email@email.com”, Login = “Login3”, Password = “Password3”. UserId сгенерирован (2) |
|
|
4 |
User{ Email = “email@email.com”, Login = “Login4”, Password = “Password4”} |
В базу данных добавлена информация о пользователе с Email = “email@email.com”, Login = “Login”, Password = “Password”. UserId сгенерирован |
В базу данных добавлена информация о пользователе с Email = “email@email.com”, Login = “Login”, Password = “Password”. UserId сгенерирован (3) |
|
|
5 |
User{ Email = “email@email.com”, Password = “Password”} |
Ошибка валидации Entity Framework |
Ошибка валидации Entity Framework |
|
|
6 |
User{UserId = 0, FIO = “Фамилия Имя Отчество”, Email = “email@email.com”, Login = “Login” (Уже существует в БД), Password = “Password”} |
Ошибка «Пользователь с таким логином уже существует» |
Ошибка «Пользователь с таким логином уже существует» |
2. Удаление информации о пользователе.
Результаты тестирования удаления информации о пользователе представлены в таблице Таблица 4.2.
Таблица 4.2. Тестирование удаления информации о пользователе
|
№ |
Входные данные |
Ожидаемый результат |
Реальный результат |
|
|
1 |
UserId = 0 (Пользователя с таким id в базе данных нет) |
Нет действий |
Нет действий |
|
|
2 |
UserId = 1 (Пользователь без корпусов) |
Удаление информации о пользователе с UserId = 1 из базы данных |
Удаление информации о пользователе UserId = 1 из базы данных |
|
|
3 |
UserId = 2 (Пользователь с одним корпусом) |
Удаление информации о пользователе с UserId = 2 из базы данных, удаление связанного корпуса |
Удаление информации о пользователе с UserId = 2 из базы данных, удаление связанного корпуса |
|
|
4 |
UserId = 3 (Пользователь с тремя корпусами) |
Удаление информации о пользователе с UserId = 3 из базы данных, удаление связанных корпусов |
Удаление информации о пользователе с UserId = 3 из базы данных, удаление связанных корпусов |
3. Изменение информации о пользователе.
Результаты тестирования изменения информации о пользователе представлены в таблице Таблица 4.3.
Таблица 4.3. Тестирование изменения информации о пользователе
|
№ |
Входные данные |
Ожидаемый результат |
Реальный результат |
|
|
1 |
null |
Ошибка «Параметр не может быть null» |
Ошибка «Параметр не может быть null» |
|
|
2 |
User{ FIO = “Фамилия Имя Отчество”, Email = “email@email.com”, Login = “Login”, Password = “Password”} |
Ошибка «Такого пользователя не существует» |
Ошибка «Такого пользователя не существует» |
|
|
3 |
User{UserId = 0, FIO = “Фамилия Имя Отчество”, Email = “email@email.com”, Login = “Login3”, Password = “Password3”} |
Ошибка «Такого пользователя не существует» |
Ошибка «Такого пользователя не существует» |
|
|
4 |
User{ UserId = 3, Email = “email2@email.com”, Login = “Login4”, Password = “Password4”} |
В базе данных изменена информация о пользователе с UserId = 3 на Email = “email2@email.com”, Login = “Login”, Password = “Password” |
В базе данных изменена информация о пользователе с UserId = 3 на Email = “email2@email.com”, Login = “Login”, Password = “Password” |
|
|
5 |
User{ UserId = 3, Email = “email@email.com”, Password = “Password”} |
Ошибка валидации Entity Framework |
Ошибка валидации Entity Framework |
|
|
6 |
User{UserId = 3, FIO = “Фамилия Имя Отчество”, Email = “email@email.com”, Login = “Login” (Уже существует в БД), Password = “Password”} |
Ошибка «Другой пользователь с таким логином уже существует» |
Ошибка «Другой пользователь с таким логином уже существует» |
4. Авторизация пользователя (получение информации о пользователе).
Результаты тестирования авторизации пользователя представлены в таблице Таблица 4.4.
Таблица 4.4. Тестирование авторизации пользователя
|
№ |
Входные данные |
Ожидаемый результат |
Реальный результат |
|
|
1 |
Login = “Login4”, Password = “Password” |
null |
null |
|
|
2 |
Login = “Login4”, Password = “Password4” |
User { UserId = 4, FIO = null, Email = “email2@email.com”, Login = “Login4”, Password = “Password4”} |
User { UserId = 4, FIO = null, Email = “email2@email.com”, Login = “Login4”, Password = “Password4”} |
5. Добавление корпуса.
Результаты тестирования добавления корпуса представлены в таблице Таблица 4.5.
Таблица 4.5. Тестирование добавления корпуса
|
№ |
Входные данные |
Ожидаемый результат |
Реальный результат |
|
|
1 |
MakeCorpus(Name = “TestName”, Documents = null, UserId = 0) |
В базу данных добавлен общий корпус без документов с названием “TestName” |
В базу данных добавлен общий корпус без документов с названием “TestName” |
|
|
2 |
MakeCommonCorpus(Name = “Test2Name”, Documents = null) |
В базу данных добавлен общий корпус без документов с названием “Test2Name” |
В базу данных добавлен общий корпус без документов с названием “Test2Name” |
|
|
3 |
MakeCorpus(Name = “Test3Name”, Documents [ { DocumentId = 0, FlatText = "Another", |
Name = "Test Document",
СorpusId = 0 }], UserId = 2)
В базу данных добавлен частный корпус с документом (DocumentId = 0, FlatText = " Another",
Name = "Test Document",
СorpusId соответствует) с названием “Test3Name”
В базу данных добавлен частный корпус с документом (DocumentId = 0, FlatText = " Another",
Name = "Test Document",
СorpusId соответствует) с названием “Test3Name”
4
MakeCorpus(Name = “TestName”, Documents = [ {
DocumentId = 0, FlatText = "Another",
Name = "Test Document",
СorpusId = 0 }, {
DocumentId = 0, FlatText = "Second Another",
Name = "Test2 Document",
СorpusId = 0 }], UserId = 3)
В базу данных добавлен частный корпус с документами (DocumentId = 0, FlatText = "Another",
Name = "Test Document",
СorpusId соответствует; DocumentId = 0, FlatText = "Just flat text second",
Name = "Test2 Document",
СorpusId соответствует) с названием “Test3Name”
В базу данных добавлен частный корпус с документами (DocumentId = 0, FlatText = "Another",
Name = "Test Document",
СorpusId соответствует; DocumentId = 0, FlatText = "Just flat text second",
Name = "Test2 Document",
СorpusId соответствует) с названием “Test3Name”
5
MakeCorpus(Name = “Test5Name”, new Documents[0], UserId = 2)
В базу данных добавлен частный корпус без документов с названием “Test5Name” и UserId=2
В базу данных добавлен частный корпус без документов с названием “Test5Name” и UserId=2
6. Изменение корпуса.
Результаты тестирования изменения корпуса представлены в таблице Таблица 4.6.
Таблица 4.6. Тестирование изменения корпуса
|
№ |
Входные данные |
Ожидаемый результат |
Реальный результат |
|
|
1 |
null |
Ошибка «Параметр не может быть null» |
Ошибка «Параметр не может быть null» |
|
|
2 |
Corpus { Name = “”, UserId = 0, CorpusId = 0} |
Ошибка «Такого корпуса не существует» |
Ошибка «Такого корпуса не существует» |
|
|
3 |
Corpus { Name = “Test”, UserId = 2, CorpusId = 1} |
Изменение корпуса в БД с CorpusId = 1 на Name = “Test” |
Изменение корпуса в БД с CorpusId = 1 на Name = “Test” |
|
|
4 |
Corpus { Name = “”, CorpusId = 1} |
Изменение корпуса в БД с CorpusId = 1 на Name = “ ” |
Изменение корпуса в БД с CorpusId = 1 на Name = “ ” |
7. Удаление корпуса.
Результаты тестирования удаления корпуса представлены в таблице Таблица 4.7.
Таблица 4.7. Тестирование удаления корпуса
|
№ |
Входные данные |
Ожидаемый результат |
Реальный результат |
|
|
1 |
CorpusId = 0 (Корпуса с таким id в базе данных нет) |
Нет действий |
Нет действий |
|
|
2 |
CorpusId = 1 (Корпус без документов) |
Удаление корпуса из базы данных |
Удаление корпуса из базы данных |
|
|
3 |
CorpusId = 3 (Корпус с одним документом) |
Удаление корпуса из базы данных, удаление связанного документа |
Удаление корпуса из базы данных, удаление связанного документа |
|
|
4 |
CorpusId = 4 (Корпус с двумя документами) |
Удаление корпуса из базы данных, удаление связанных документов |
Удаление корпуса из базы данных, удаление связанных документов |
8. Получение информации о корпусах.
Результаты тестирования получения информации о корпусах пользователя представлены в таблице Таблица 4.8.