選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

DbPediaDataAccess.cs 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Luticate2.Utils.Dbo.Basic;
  5. using Luticate2.Utils.Dbo.PaginatedRequest;
  6. using Luticate2.Utils.Dbo.Result;
  7. using Microsoft.Extensions.Logging;
  8. using VDS.RDF.Nodes;
  9. using VDS.RDF.Query;
  10. using WebApiWebSem.Dbo.Articles;
  11. using WebApiWebSem.Dbo.ArticlesFields;
  12. namespace WebApiWebSem.DataAccess
  13. {
  14. public class DbPediaDataAccess
  15. {
  16. private readonly SparqlRemoteEndpoint _sparqlRemoteEndpoint;
  17. private readonly ILogger<DbPediaDataAccess> _logger;
  18. protected string Prefixes = @"
  19. PREFIX owl: <http://www.w3.org/2002/07/owl#>
  20. PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
  21. PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
  22. PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
  23. PREFIX foaf: <http://xmlns.com/foaf/0.1/>
  24. PREFIX dc: <http://purl.org/dc/elements/1.1/>
  25. PREFIX : <http://dbpedia.org/resource/>
  26. PREFIX dbpedia2: <http://dbpedia.org/property/>
  27. PREFIX dbpedia: <http://dbpedia.org/>
  28. PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
  29. PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
  30. ";
  31. public DbPediaDataAccess(SparqlRemoteEndpoint sparqlRemoteEndpoint, ILogger<DbPediaDataAccess> logger)
  32. {
  33. _sparqlRemoteEndpoint = sparqlRemoteEndpoint;
  34. _logger = logger;
  35. }
  36. protected string Escape(string str)//TODO
  37. {
  38. return str.Replace('\'', ' ').Replace('"', ' ');
  39. }
  40. protected LuResult<SparqlResultSet> Query(string query)
  41. {
  42. _logger.LogInformation(query);
  43. try
  44. {
  45. var results = _sparqlRemoteEndpoint.QueryWithResultSet(query);
  46. return LuResult<SparqlResultSet>.Ok(results);
  47. }
  48. catch (Exception e)
  49. {
  50. return LuResult<SparqlResultSet>.Error(LuStatus.BackendError, e);
  51. }
  52. }
  53. protected ArticlesDbo ModelToDbo(SparqlResult result)
  54. {
  55. var dbo = new ArticlesDbo
  56. {
  57. Fields = new List<ArticlesFieldsDbo>()
  58. };
  59. foreach (var variable in result.Variables)
  60. {
  61. string data = null;
  62. var v = result[variable];
  63. if (v != null)
  64. {
  65. data = v.AsValuedNode().AsString();
  66. }
  67. if (variable == "id")
  68. {
  69. dbo.Id = data.Split('/').Last();
  70. }
  71. else if (variable == "abstract")
  72. {
  73. dbo.Text = data;
  74. }
  75. else if (variable == "pictureUrl")
  76. {
  77. dbo.PictureUrl = data;
  78. }
  79. else if (variable == "pictureDesc")
  80. {
  81. dbo.PictureCaption = data;
  82. }
  83. else
  84. {
  85. if (data != null)
  86. {
  87. dbo.Fields.Add(new ArticlesFieldsDbo
  88. {
  89. Property = variable,
  90. Type = "text/plain",
  91. Value = data
  92. });
  93. }
  94. }
  95. }
  96. return dbo;
  97. }
  98. public LuResult<LuPaginatedDbo<ArticlesDbo>> GetMultiple(LuPaginatedRequestDbo request)
  99. {
  100. var type = ArticlesDataAccess.GetFilterType(request.Filter);
  101. string querySelect = null;
  102. string queryWhereId = null;
  103. string queryWhereVars = null;
  104. if (type == "home")
  105. {
  106. querySelect = "?id ?abstract ?pictureUrl ?pictureDesc";
  107. queryWhereId = @"?id foaf:isPrimaryTopicOf wikipedia-en:World_War_II .";
  108. queryWhereVars = @"
  109. OPTIONAL { ?id dbo:abstract ?abstract FILTER(lang(?abstract) = 'en') }
  110. OPTIONAL { ?id foaf:depiction ?pictureUrl }
  111. OPTIONAL { ?id dbpedia-owl:depictionDescription ?pictureDesc }
  112. BIND ((?abstract) AS ?search)";
  113. }
  114. else if (type == "persons")
  115. {
  116. querySelect = "?id ?abstract ?pictureUrl ?pictureDesc (MIN(?name) AS ?name) (str(?birthDate) AS ?birthDate) (str(?deathDate) AS ?deathDate)";
  117. queryWhereId = @"?id rdf:type dbo:Person ;
  118. ?type dbr:World_War_II .";
  119. queryWhereVars = @"
  120. ?id dbp:name ?name .
  121. OPTIONAL { ?id dbo:abstract ?abstract FILTER(lang(?abstract) = 'en') }
  122. OPTIONAL { ?id foaf:depiction ?pictureUrl }
  123. OPTIONAL { ?id dbpedia-owl:depictionDescription ?pictureDesc }
  124. OPTIONAL { ?id dbp:birthDate ?birthDate }
  125. OPTIONAL { ?id dbp:deathDate ?deathDate }
  126. FILTER (lang(?name) = 'en')
  127. BIND (CONCAT(?name) AS ?search)";
  128. }
  129. else if (type == "locations")
  130. {
  131. querySelect = "?id ?name ?abstract ?pictureUrl ?pictureDesc (str(MIN(?date) as ?date) as ?date) (group_concat(distinct ?combatant;separator=', ') as ?combatant) (group_concat(distinct ?commanderName;separator=', ') as ?commander)";
  132. queryWhereId = @"?ww foaf:isPrimaryTopicOf wikipedia-en:World_War_II ;
  133. dbo:place ?id.";
  134. queryWhereVars = @"
  135. ?id foaf:name ?name .
  136. OPTIONAL { ?id dbo:abstract ?abstract FILTER(lang(?abstract) = 'en') }
  137. OPTIONAL { ?id foaf:depiction ?pictureUrl }
  138. OPTIONAL { ?id dbpedia-owl:depictionDescription ?pictureDesc }
  139. OPTIONAL { ?id dbo:date ?date }
  140. OPTIONAL { ?id dbp:combatant ?combatant }
  141. OPTIONAL { ?id dbp:commander ?commanderName }
  142. FILTER (lang(?name) = 'en')
  143. BIND (CONCAT(?name) AS ?search)";
  144. }
  145. else if (type == "countries")
  146. {
  147. querySelect = "?id (MIN(?name) as ?name) ?abstract ?pictureUrl ?pictureDesc ";
  148. queryWhereId = @"?id a <http://dbpedia.org/ontology/Country> ;
  149. ?type dbr:World_War_II .";
  150. queryWhereVars = @"
  151. ?id foaf:name ?name .
  152. OPTIONAL { ?id dbo:abstract ?abstract FILTER(lang(?abstract) = 'en') }
  153. OPTIONAL { ?id foaf:depiction ?pictureUrl }
  154. OPTIONAL { ?id dbpedia-owl:depictionDescription ?pictureDesc }
  155. FILTER (lang(?name) = 'en')
  156. BIND (CONCAT(?name) AS ?search)";
  157. }
  158. var filter = $"FILTER regex(?search, '{request.Filter.Query}', 'i')";
  159. var count = Query(string.Format(@"{0}
  160. SELECT (COUNT(?id) AS ?count) WHERE {{
  161. SELECT DISTINCT {1} WHERE {{
  162. {2}
  163. {3}
  164. {4}
  165. }}
  166. }}
  167. ", Prefixes, querySelect, queryWhereId, queryWhereVars, filter));
  168. if (!count)
  169. {
  170. return count.To<LuPaginatedDbo<ArticlesDbo>>();
  171. }
  172. var res = Query(string.Format(@"{0}
  173. SELECT DISTINCT {1} WHERE {{
  174. {2}
  175. {3}
  176. {4}
  177. }}
  178. ORDER BY {5}
  179. LIMIT {6}
  180. OFFSET {7}", Prefixes, querySelect, queryWhereId, queryWhereVars, filter, request.OrderBy.ToDbPediaModel(),
  181. request.PerPage, request.Page * request.PerPage));
  182. if (!res)
  183. {
  184. return res.To<LuPaginatedDbo<ArticlesDbo>>();
  185. }
  186. var results = new LuPaginatedDbo<ArticlesDbo>
  187. {
  188. Count = count.Data.Results.First()["count"].AsValuedNode().AsInteger(),
  189. Data = res.Data.Results.Select(ModelToDbo).Select(dbo =>
  190. {
  191. dbo.Type = type;
  192. return dbo;
  193. }).ToList()
  194. };
  195. return LuResult<LuPaginatedDbo<ArticlesDbo>>.Ok(results);
  196. }
  197. }
  198. }