В настоящее время я столкнулся с проблемой, связанной с моей таблицей данных, реализованной в ReactJS. Я получаю данные из elasticsearch и заполняю ими данные. Процесс извлечения данных отлично работает без примененного фильтра, однако, когда я применяю фильтры к данным, таблица данных остается пустой, даже если в источнике данных есть соответствующие записи.
Структура параметров, которые я отправляю, выглядит следующим образом:
{
pageIndex: 1,
pageSize: 10,
sort: { order: '', key: '' },
query: '',
filterData: {
analysis: [ '0', '1', '2', '3' ],
threat_level_id: [ '1', '2', '3', '4' ],
}
}
Конечная точка:
POST /api/v1/events/public/список
Контроллер:
exports.getPublicEvents = async (req, res) => {
try {
client.ping()
const { pageIndex, pageSize, sort, query, filterData } = req.body
let esQuery = {
index: 'ns_*',
body: {
query: {
bool: {
must: [
{
match_all: {},
},
],
filter: [],
},
},
from: (pageIndex - 1) * pageSize,
size: pageSize,
},
}
if (query) {
esQuery.body.query.bool.must = [
{
match: {
'Event.info': {
query: query,
fuzziness: 'AUTO',
},
},
},
]
}
if (filterData.analysis.length > 0) {
esQuery.body.query.bool.filter.push({
terms: {
'Event.analysis': filterData.analysis,
},
})
}
if (filterData.threat_level_id.length > 0) {
esQuery.body.query.bool.filter.push({
terms: {
'Event.threat_level_id': filterData.threat_level_id,
},
})
}
let esResponse = await client.search(esQuery)
let data = esResponse.hits.hits.map((hit) => hit._source)
let total = esResponse.hits.total.value
res.status(200).json({
status: 'success',
data: data,
total: total,
})
} catch (error) {
res.status(500).json({
error: 'Error connecting to Elasticsearch',
errorMessage: error.message,
})
}
}
Контроллер ниже без фильтров и работает нормально.
exports.getPublicEvents = async (req, res) => {
try {
client.ping()
const { pageIndex, pageSize, sort, query } = req.body
let esQuery = {
index: 'ns_*',
body: {
query: {
match_all: {},
},
from: (pageIndex - 1) * pageSize,
size: pageSize,
},
}
if (query) {
esQuery.body.query = {
match: {
'Event.info': {
query: query,
fuzziness: 'AUTO',
},
},
}
}
let esResponse = await client.search(esQuery)
let data = esResponse.hits.hits.map((hit) => hit._source)
let total = esResponse.hits.total.value
res.status(200).json({
status: 'success',
data: data,
total: total,
})
} catch (error) {
res.status(500).json({
error: 'Error connecting to Elasticsearch',
errorMessage: error.message,
})
}
}
Версия ElasticSearch: 7.17.8
Результат: console.info(JSON.stringify(esQuery))
{
"index": "INDEX_NAME",
"body": {
"query": {
"bool": {
"must": [{ "match_all": {} }],
"filter": [
{ "terms": { "Event.analysis": ["0", "1", "2"] } },
{ "terms": { "Event.threat_level_id": ["1", "2", "3", "4"] } }
]
}
},
"from": 0,
"size": 10
}
}
Данные в схеме elasticsearch
{
"@version": "1",
"@timestamp": "2023-02-01T14:43:09.997Z",
"Event": {
"info": ".......................",
"description": ".......................",
"analysis": 0,
"threat_level_id": "4",
"created_at": 1516566351,
"uuid": "5a64f74f0e543738c12bc973322",
"updated_at": 1675262417
}
}
Отображение индекса
{
"index_patterns": ["INDEX_NAME"],
"template": "TEMPLATE_NAME",
"settings": {
"number_of_replicas": 0,
"index.mapping.nested_objects.limit": 10000000
},
"mappings": {
"dynamic": false,
"properties": {
"@timestamp": {
"type": "date"
},
"Event": {
"type": "nested",
"properties": {
"date_occured": {
"type": "date"
},
"threat_level_id": {
"type": "integer"
},
"description": {
"type": "text"
},
"is_shared": {
"type": "boolean"
},
"analysis": {
"type": "integer"
},
"uuid": {
"type": "text"
},
"created_at": {
"type": "date"
},
"info": {
"type": "text"
},
"shared_with": {
"type": "nested",
"properties": {
"_id": {
"type": "text"
}
}
},
"updated_at": {
"type": "date"
},
"author": {
"type": "text"
},
"Attributes": {
"type": "nested",
"properties": {
"data": {
"type": "text"
},
"type": {
"type": "text"
},
"uuid": {
"type": "text"
},
"comment": {
"type": "text"
},
"category": {
"type": "text"
},
"value": {
"type": "text"
},
"timestamp": {
"type": "date"
}
}
},
"organisation": {
"type": "nested",
"properties": {
"name": {
"type": "text"
},
"uuid": {
"type": "text"
}
}
},
"Tags": {
"type": "nested",
"properties": {
"color": {
"type": "text"
},
"name": {
"type": "text"
}
}
},
"TLP": {
"type": "nested",
"properties": {
"color": {
"type": "text"
},
"name": {
"type": "text"
}
}
}
}
}
}
}
}
Параметры, которые я отправляю, упоминаются в моем вопросе, а возвращаемые данные пусты и не получают ошибок в клиенте es.
Можете ли вы распечатать запрос, который генерируется при применении фильтров? как JSON.stringify(esQuery)
. Также вы можете указать, какую версию клиента ES вы используете, потому что в последних версиях параметр body
исчез, а query
следует указывать на верхнем уровне?
Я обновил свой вопрос и добавил версию ES и результат JSON.stringify(esQuery)
@Val я также добавил схему данных в ES
Я вижу, что в ваших документах есть Event.threat_level
, но в вашем запросе есть Event. threat_level_id
@Val неважно, что я только что изменил имя свойства
примечание: size/from выходит за пределы раздела body, который должен содержать только часть запроса
@Val Контроллер без фильтров отлично работает, используя from & size внутри тела!
Просто сказать, что это не соответствует договору, это может сработать, но они могут быть не приняты во внимание. В любом случае, это не проблема. Сколько обращений вы получаете, выполняя этот запрос непосредственно в Kibana Dev Tools?
И меня все еще беспокоит, что у вас было threat_level
против threat_level_id
, если вы копировали/вставляли свой документ непосредственно в SO
@Val Это была просто опечатка, и я обновил ее в вопросе. его id_уровня_угрозы
@Val, вы нашли что-нибудь, что может помочь мне решить эту проблему, сэр?
Вы не ответили на мой последний вопрос: сколько обращений вы получаете при выполнении этого запроса непосредственно в Kibana Dev Tools для того же индекса?
@Val Я получаю пустые хиты: «хиты»: { «всего»: { «значение»: 0, «отношение»: «экв» }, «max_score»: ноль, «хиты»: []}
Когда я удаляю часть фильтра, запрос работает нормально. "filter": [ { "terms": { "Event.analysis": ["0", "1", "2"] } }, { "terms": { "Event.threat_level_id": ["1", "2", "3", "4"] } } ]
Можете ли вы поделиться своим отображением индекса в своем вопросе?
@Val Я обновил свой вопрос и добавил отображение индекса
Спасибо, но обратите внимание, что я все еще вижу поле с именем threat_level
, а не threat_level_id
в вашем сопоставлении. Хотя добавил мой ответ
Не беспокойтесь об этом, потому что я обновил id_level_id до уровня угрозы в своем реальном сопоставлении.
Event
— это вложенное поле, поэтому вам нужно использовать вложенные запросы, например:
{
"index": "INDEX_NAME",
"body": {
"query": {
"bool": {
"must": [{ "match_all": {} }],
"filter": [
{
"nested": {
"path": "Event",
"query": {"terms": { "Event.analysis": ["0", "1", "2"] }}
}
},
{
"nested": {
"path": "Event",
"query": {"terms": { "Event.threat_level_id": ["1", "2", "3", "4"] }}
}
}
]
}
},
"from": 0,
"size": 10
}
}
Спасибо, мистер @Val, за вашу помощь. Теперь работает :)
Какие значения вы отправляете
query
в свой контроллер? это первый фрагмент? У вас нет ошибок отes client
? Логи, которые мы могли бы проанализировать?