Почему мой запрос ElasticSeach возвращает нулевой документ?

Я пытаюсь запросить домен AWS ElasticSearch от работника Lambda.

Для этого я использую https://www.npmjs.com/package/http-aws-es и основной javascript клиент для эластичного поиска.

Я запрашиваю документы со следующими соответствующими полями:

  • Поле ref — строка
  • Поле status — строка ENUM (REMOVED, BLOCKED, PUBLISHED, PENDING, VERIFIED)
  • Поле field — массив строк
  • Поле thematics — массив строк

Чего я хочу добиться, так это:

  1. Отфильтровать все документы, которые не являются ни PUBLISHED, ни VERIFIED, ни где установлено поле ref
  2. Вернуть лучшие совпадения с моим аргументом keywwords (массив строк) относительно значений в field и thematics
  3. Сортировать, чтобы документы со статусом PUBLISHED располагались первыми
  4. Ограничьте количество результатов до 20

Я нашел оператора more_like_this и попробовал. Я шаг за шагом строю свой запрос, и актуальная версия, по крайней мере, не возвращает ошибку, но документы не возвращаются. Он по-прежнему пропускает фильтр ref + #3 и #4 сверху. Вот запрос:

  const client = new elasticsearch.Client({
      host: ELASTICSEARCH_DOMAIN,
      connectionClass: httpAwsEs,
      amazonES: {
        region: AWS_REGION,
        credentials: new AWS.EnvironmentCredentials('AWS')
      }
    })
    let keywords = event.arguments.keywords
    let rst = await client.search({
      body: {
        'query': {
          'bool': {
            'filter': {
              'bool': {
                'must_not': [
                  {
                    'term': {
                      'status': 'REMOVED'
                    }
                  },
                  {
                    'term': {
                      'status': 'PENDING'
                    }
                  },
                  {
                    'term': {
                      'status': 'BLOCKED'
                    }
                  }
                ]
              }
            },
            'must': {
              'more_like_this': {
                'fields': ['field', 'thematics'],
                'like': keywords,
                'min_term_freq': 1,
                'max_query_terms': 2
              },
              'should': [
                {
                  'term': {
                    'status': 'PUBLISHED'
                  }
                }
              ]
            }
          }
        }
      }

    })
    console.log(rst)
    return rst

Я должен загрузить свой лямбда-код для отладки, и это сильно усложняет отладку. Поскольку я никогда раньше не делал ES-запросов, я хотел получить хотя бы несколько советов о том, как это сделать, или узнать, неправильно ли я использую синтаксис ES-запросов.


РЕДАКТИРОВАТЬ:

В соответствии с запросом, вот мое отображение индекса (с типом JS):

  • текст города (строка)
  • contact_email текст (строка)
  • текст contact_entity (строка)
  • contact_firstname текст (строка)
  • contact_lastname текст (строка)
  • текст контактов (строковый список)
  • текст страны (строка)
  • Дата создания (строка)
  • текст описания (строка)
  • текст editKey (строка)
  • текст поля (строка)
  • текст идентификатора (строка)
  • текст имени (строка)
  • текст pubId (строка)
  • текст ссылки (строка)
  • текст состояния (строка)
  • текст состояния (строка)
  • тематический текст (массив строк)
  • введите текст (массив строк)
  • updateAt (строка)
  • текст URL-адреса (строка)
  • Текст VerifyKey (строка)
  • текст зоны (массив строк)

Взято из консоли управления эластичным поиском AWS (вкладки индекса › сопоставления)


person Billybobbonnet    schedule 26.05.2020    source источник


Ответы (1)


В вашем запросе есть одна или две проблемы (should внутри must и must_not внутри filter). Вместо этого попробуйте упрощенный запрос ниже:

{
  'query': {
    'bool': {
      'must_not': [
        {
          'term': {
            'status.keyword': 'REMOVED'
          }
        },
        {
          'term': {
            'status.keyword': 'PENDING'
          }
        },
        {
          'term': {
            'status.keyword': 'BLOCKED'
          }
        }
      ],
      'must': [
        {
          'more_like_this': {
            'fields': [
              'field',
              'thematics'
            ],
            'like': keywords,
            'min_term_freq': 1,
            'max_query_terms': 2
          }
        }
      ],
      'should': [
        {
          'term': {
            'status.keyword': 'PUBLISHED'
          }
        }
      ]
    }
  }
}
person Val    schedule 26.05.2020
comment
Большое спасибо за то, что поставили меня на правильный путь. Вы сэкономили мне много времени. Ваше здоровье! - person Billybobbonnet; 26.05.2020
comment
Круто, рад, что помогло! - person Val; 26.05.2020
comment
Получается, что must_not не учитывается в результатах запроса. Я получаю документы с запрещенными значениями (например, статус: «БЛОКИРОВАН»). Если я заменю его на filter, результат не будет возвращен. ЕС версия 6.2. Я также безуспешно пытался заменить more_like_this на match_phrase. Любое предложение? Должен ли я открыть еще один вопрос? Спасибо еще раз - person Billybobbonnet; 27.05.2020
comment
Можете ли вы показать свое отображение индекса? Я мог бы знать причину - person Val; 27.05.2020
comment
Мне нужно сопоставление, которое исходит от ES, то есть то, которое вы получаете от GET your-index-name/_mapping - person Val; 27.05.2020
comment
Конечная точка ES защищена cognito. Я буду использовать свою лямбду, чтобы получить сопоставления. Извините за задержку. - person Billybobbonnet; 27.05.2020
comment
В какой-то момент вы, возможно, захотите прочитать это: elastic.co/aws-elasticsearch-service - person Val; 27.05.2020
comment
Я захвачен экосистемой AWS, так как использовал amplify и их директиву @searchable для создания стека ES. Это очень дорого и, конечно, уступает по характеристикам. Однако мне пришлось бы изменить триггер DynamoDB для репликации новых записей в ES, а также мой поисковый запрос (поверх приложения Sync graphQL API). У меня очень плотный график, и до сих пор мой опыт ES не что иное, как боль. - person Billybobbonnet; 27.05.2020
comment
Хорошо, тогда давайте посмотрим на это сопоставление - person Val; 27.05.2020
comment
Давай, повтори обновленный запрос (увидишь, что status заменено на status.keyword) - person Val; 27.05.2020
comment
Наконец, это работает. Большое спасибо за вашу помощь и терпение. Я бы проголосовал за вас дважды, если бы мог :) - person Billybobbonnet; 27.05.2020
comment
Не беда, рад, что смог помочь! - person Val; 27.05.2020