2015-10-10 6 views
2

Я очень новый для Elasticsearch, и я должен выполнить следующий запрос:Elasticsearch термин запрос не дает никаких результатов

GET book-lists/book-list/_search 
{ 
    "query":{ 
     "filtered":{ 
     "filter":{ 
      "bool":{ 
       "must":[ 
        { 
        "term":{ 
         "title":"Sociology" 
        } 
        }, 
        { 
        "term":{ 
         "idOwner":"17xxxxxxxxxxxx45" 
        } 
        } 
       ] 
      } 
     } 
     } 
    } 
} 

Согласно API Elasticsearch, это эквивалентно псевдо-SQL:

SELECT document 
FROM book-lists 
WHERE title = "Sociology" 
     AND idOwner = 17xxxxxxxxxxxx45 

проблема заключается в том, что мой документ выглядит следующим образом:

{ 
    "_index":"book-lists", 
    "_type":"book-list", 
    "_id":"AVBRSvHIXb7carZwcePS", 
    "_version":1, 
    "_score":1, 
    "_source":{ 
     "title":"Sociology", 
     "books":[ 
     { 
      "title":"The Tipping Point: How Little Things Can Make a Big Difference", 
      "isRead":true, 
      "summary":"lorem ipsum", 
      "rating":3.5 
     } 
     ], 
     "numberViews":0, 
     "idOwner":"17xxxxxxxxxxxx45" 
    } 
} 

И запрос Elasticsearch выше г ничего не вернуть.

В то время как этот запрос возвращает документ выше:

GET book-lists/book-list/_search 
{ 
    "query":{ 
     "filtered":{ 
     "filter":{ 
      "bool":{ 
       "must":[ 
        { 
        "term":{ 
         "numberViews":"0" 
        } 
        }, 
        { 
        "term":{ 
         "idOwner":"17xxxxxxxxxxxx45" 
        } 
        } 
       ] 
      } 
     } 
     } 
    } 
} 

Это заставляет меня подозревать, что тот факт, что «название» одно и то же имя для двух полей для чего-то.

Есть ли способ исправить это, не переименовывая ни одно из полей. Или я скучаю по нему где-то еще?

Спасибо за каждого, кто пытается помочь.

+0

Я столкнулся с такой же проблемой с отфильтрованным запросом. можете ли вы попытаться сделать социологию в нижнем регистре в своем запросе. –

+0

У вас есть явное сопоставление с вашим индексом или вы используете динамическое сопоставление? – solarissmoke

+0

@Undefined_variable, который работал oO – Mayas

ответ

6

Ваша проблема описана in the documentation.

Я подозреваю, что у вас нет явного сопоставления индекса, что означает, что elasticsearch будет использовать динамическое сопоставление.

Для строковых полей он передаст строку через standard analyzer, которая удерживает ее (среди прочего). Вот почему ваш запрос не работает.

варианты:

  1. Укажите явное отображение на поле так, что она не анализируется перед сохранением в индексе (index: not_analyzed).
  2. Очистите свой запрос терминов перед его отправкой в ​​elasticsearch (в этом конкретном запросе нижняя шкала будет работать, но обратите внимание, что стандартный анализатор также выполняет другие действия, такие как удаление стоп-слов, поэтому в зависимости от названия у вас могут быть проблемы).
  3. Используйте другой тип запроса (например, query_string вместо term, который проанализирует запрос перед его запуском).

При взгляде на данные, которые вы храните, вероятно, необходимо указать явное сопоставление not_analyzed.

Для варианта три ваш запрос будет выглядеть следующим образом:

{ 
    "query":{ 
     "filtered":{ 
     "filter":{ 
      "bool":{ 
       "must":[ 
        { 
        "query_string":{ 
         "fields": ["title"], 
         "analyzer": "standard", 
         "query": "Sociology" 
        } 
        }, 
        { 
        "term":{ 
         "idOwner":"17xxxxxxxxxxxx45" 
        } 
        } 
       ] 
      } 
     } 
     } 
    } 
} 

Обратите внимание, что query_string запроса имеет специальный синтаксис (например, OR и AND, не рассматривается как литералы), который означает, что вы должны быть осторожны, что вы даете это. По этой причине явное сопоставление с фильтром терминов, вероятно, более подходит для вашего варианта использования.

+0

, можете ли вы предоставить правильный запрос для третьего варианта, пожалуйста? Я заменил 'term' на' query_string', но я получаю сообщение об ошибке – Mayas

+1

Я добавил пример запроса к ответу. Не проверено, но это дает вам общую идею. Если можно, я бы предположил, что вы смотрите на явное сопоставление, поскольку в этом случае это будет намного более эффективно и предсказуемо. – solarissmoke

1

Чтобы расширить решение solarissmoke, в то время как содержимое этого поля будет проходить через стандартный анализатор, ваш запрос не будет.Если вы ссылаетесь на документацию Elasticsearch на запрос термина, вы увидите, что запросы термина не анализируются.

Вопрос соответствия, вероятно, более подходит для вашего случая. То, что вы запрашиваете, будет анализироваться так же, как и содержимое поля заголовка по умолчанию. Запрос query_string приносит гораздо больше в таблицу, и вы должны просмотреть документацию, если планируете ее использовать.

Так же в значительной степени то, что вы были с небольшой подстройкой:

GET book-lists/book-list/_search 
{ 
    "query":{ 
     "filtered":{ 
     "filter":{ 
      "bool":{ 
       "must":[ 
        { 
        "match":{ 
         "title":"Sociology" 
        } 
        }, 
        { 
        "term":{ 
         "idOwner":"17xxxxxxxxxxxx45" 
        } 
        } 
       ] 
      } 
     } 
     } 
    } 
} 

Важно отметить прохождение строчной версии условий для термина запроса (хак - не кажется хорошей идеей, учитывая то, что solarissmoke расскажете о других особенностях стандартного анализатора, как стоп-фильтр), используя запрос QUERY_STRING, или с помощью запроса матча еще очень отличается от запроса SQL вы описали:

SELECT document 
FROM book-lists 
WHERE title = "Sociology" 
     AND idOwner = 17xxxxxxxxxxxx45 

с тех Elasticsearch запросами, вы может соответствовать записи, где i dOwner может быть тем же, но заголовок может быть чем-то вроде «Another Sociology Title», который отличается от того, что вы ожидаете от этого SQL. Вот некоторые большие вещи из документации и другой StackOverflow пост, который будет подробно останавливаться на том, что происходит, когда термин запросы и фильтры подходят, и получать точные совпадения:

Elasticsearch : Finding Exact Values

Stackoverflow : Exact (not substring) matching in Elasticsearch

+0

Ваша точка зрения очень важна, может быть какое-то название, например, «современные авторы социологии», и я также могу сделать его доступным для поиска, следовательно, проанализировать его. Я могу скоро перейти к вашему решению. – Mayas

1

У меня есть описал этот вопрос в этом blog. Проблема возникает из-за токенизации по умолчанию в Elasticsearch. В том же, я изложил 2 решения. Один из них включает флаг not_analyzed в обязательном поле, а другой - использовать токенинг ключевых слов.

Смежные вопросы