34
35:- module(elastic,
36 [ es_get/2, 37 es_put/2,
38 es_post/2, 39 es_post/3, 40 es_create_index/2,
41 es_delete_index/1,
42 es_add/4, 43 es_search/3
44 ]). 45:- use_module(library(http/http_open)). 46:- use_module(library(http/http_json)). 47:- use_module(library(http/json)). 48:- use_module(library(option)). 49:- use_module(library(uri)). 50
51:- multifile
52 es_server/2.
70es_get(Path, Result) :-
71 es_url(Path, URL, Options),
72 http_open(URL, In,
73 [ status_code(Status)
74 | Options
75 ]),
76 call_cleanup(reply(Status, In, Result), close(In)).
77
78es_put(Path, Data) :-
79 es_url(Path, URL, Options),
80 http_open(URL, In, [ method(put),
81 post(json(Data)),
82 status_code(Status)
83 | Options
84 ]),
85 call_cleanup(ok_reply(Status, In), close(In)).
86
87es_post(Path, Data) :-
88 es_url(Path, URL, Options),
89 http_open(URL, In, [ post(json(Data)),
90 status_code(Status)
91 | Options
92 ]),
93 call_cleanup(ok_reply(Status, In), close(In)).
94
95es_post(Path, Data, Result) :-
96 es_url(Path, URL, Options),
97 http_open(URL, In, [ post(json(Data)),
98 status_code(Status)
99 | Options
100 ]),
101 call_cleanup(reply(Status, In, Result), close(In)).
109es_add(Index, Data, Reply, Options) :-
110 option(id(Id), Options),
111 !,
112 es_post(Index/'_doc'/Id, Data, Reply).
113es_add(Index, Data, Reply, _Options) :-
114 es_post(Index/'_doc', Data, Reply).
121es_search(Index, For, Result) :-
122 es_post(Index/'_search', For, Result).
130es_create_index(Index, Mapping) :-
131 es_put(Index,
132 #{mappings:
133 #{properties:Mapping}
134 }).
135
136es_delete_index(Index) :-
137 es_url(Index, URL, Options),
138 http_open(URL, In, [ method(delete),
139 status_code(Status)
140 | Options
141 ]),
142 call_cleanup(ok_reply(Status, In), close(In)).
150es_url(Path, URL, [connection('Keep-alive')|Options]) :-
151 es_server(URL0, Options),
152 path_segments(Path1, Path),
153 uri_edit(path(Path1), URL0, URL).
154
155:- public tls_verify/5. 156tls_verify(_SSL, _ProblemCert, _AllCerts, _FirstCert, verified) :-
157 !.
158tls_verify(_SSL, _ProblemCert, _AllCerts, _FirstCert, hostname_mismatch) :-
159 !.
160tls_verify(_SSL, _ProblemCert, _AllCerts, _FirstCert, _Error) :-
161 fail.
170ok_reply(Status, _In) :-
171 between(200, 299, Status),
172 !.
173ok_reply(Status, In) :-
174 json_read_dict(In, Result, []),
175 print_message(error, es_error(Status, Result)).
176
177reply(Status, In, Reply) :-
178 between(200, 299, Status),
179 !,
180 json_read_dict(In, Reply, []).
181reply(Status, In, null) :-
182 json_read_dict(In, Result, []),
183 throw(error(es_error(Status, Result), _)).
189path_segments(Path, Segments) :-
190 nonvar(Path),
191 !,
192 atomic_list_concat(Segments, /, Path).
193path_segments(Path, Path) :-
194 atomic(Path),
195 !.
196path_segments(Path, Segments) :-
197 phrase(segments(Segments), List),
198 atomic_list_concat(List, /, Path).
199
200segments(A/B) -->
201 !,
202 segments(A),
203 segments(B).
204segments(A) -->
205 [A].
206
207 210
211:- multifile
212 prolog:message//1,
213 prolog:error_message//1. 214
215prolog:error_message(es_error(Code, Message)) -->
216 [ 'Elastic search: got reply ~w:'-[Code], nl,
217 ' ~@'-[print_term(Message, [output(current_output)])],
218 nl
219 ]
Core Elastic search interface
This module is a thin layer over the Elastic REST interface. Eventually this should go into a pack. */