Множество функций в функции restify для клиента Flexiblesearch
Я создаю REST API с использованием узла и обновляю эти сообщения с помощью базы данных asticsearch. Теперь, когда я удаляю объект, я хочу, чтобы это выполняло каскадное удаление некоторых других объектов. Я знаю, что на самом деле это не то, для чего нужно использовать эластичный поиск, но терпите меня.
Итак, вот мой код:
function deleteHostname(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
var endpoints = [];
client.search({
index: 'test',
type: 'something',
body: {
from: 0, size: 100,
query: {
match: {
hostname: 'www.test.com'
}
}
}
}).then(function (error, resp) {
if(error) {
res.send(error);
}
endpoints = resp.hits.hits;
for (index = 0, len = endpoints.length; index < len; ++index) {
client.delete({
index: 'test',
type: 'something',
id: endpoints[index]._id
}, function (error, response) {
if(error) {
res.send(error);
}
});
}
res.send(endpoints);
return next();
});
}
В общем, я просто хочу искать любые объекты с именем хоста www.test.com (я просто жестко запрограммировал это, чтобы проверить это). Затем я хочу удалить все объекты, которые я нашел. Это следует пути ошибки и посылает мне это:
{
"took":1,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"failed":0
},
"hits":{
"total":1,
"max_score":2.098612,
"hits":[
{
"_index":"test",
"_type":"something",
"_id":"123456",
"_score":2.098612,
"_source":{
"duration":107182,
"date":"2016-05-04 00:54:43",
"isExceptional":true,
"hostname":"www.test.com",
"eta":613,
"hasWarnings":false,
"grade":"A+",
"ipAddress":"ipip",
"progress":100,
"delegation":2,
"statusMessage":"Ready"
}
}
]
}
}
Так что, на мой взгляд, это не похоже на ошибку? Так почему я получаю это как ошибку? Если я удалю:
if(error) {
res.send(error);
}
Из моего кода я не получу никакого ответа.
1 ответ
Вы должны изменить свой код следующим образом (см. Изменения, обозначенные как ->
налево):
if(error) {
1-> return res.send(error);
}
endpoints = resp.hits.hits;
for (index = 0, len = endpoints.length; index < len; ++index) {
2-> (function(id){
client.delete({
index: 'test',
type: 'something',
3-> id: id
}, function (error, response) {
if(error) {
4-> next(error);
}
});
5-> })(endpoints[index._id]);
}
6-> //res.send(endpoints);
Я сейчас объясняю каждое изменение:
- Если вы этого не сделаете
return
Вы отправите сообщение об ошибке, а затем продолжите обработку попаданий. - (3/5) С
client.delete
это асинхронная функция, вы должны вызывать ее в анонимной функции - В случае ошибки вам нужно позвонить
next(error)
неres.send
- Вы не можете отправить ответ в этот момент, так как ваш цикл for может быть еще не завершен. Вместо цикла, вы должны использовать отличный
async
вместо библиотеки (см. пример использованияasynch.each
ниже)
Асинхронный пример:
var async = require('async');
...
if(error) {
return res.send(error);
}
endpoints = resp.hits.hits;
async.each(endpoints,
function(endpoint, callback) {
client.delete({
index: 'test',
type: 'something',
id: endpoint._id
}, callback);
},
// this is called when all deletes are done
function(err){
if (err) {
next(err);
} else {
res.send(endpoints);
next();
}
}
);
Еще одно решение для достижения именно того, чего вы хотите, - использовать плагин delete by query. Эта функция позволяет вам сделать все вышеизложенное в одном запросе.
Если вы все еще используете ES 1.x, удаление по запросу все еще является частью ядра, и вы можете просто вызвать deleteByQuery
функция клиента Javascript.
Если вы используете ES 2.x, удаление по запросу теперь является плагином, поэтому вам нужно установить его, а затем также потребовать библиотеку расширений deleteByQuery для клиента Javascript
function deleteHostname(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
client.deleteByQuery({
index: 'test',
type: 'something',
body: {
query: {
match: { hostname: 'www.test.com' }
}
}
}, function (error, response) {
if (error) {
next(error);
} else {
res.send(endpoints);
next();
}
});
}