2015-08-03 3 views
1

У меня есть индекс по имени test_blocksПочему мой эластичный поисковый запрос не возвращает текст, проанализированный английским анализатором?

{ 
    "test_blocks" : { 
    "aliases" : { }, 
    "mappings" : { 
     "block" : { 
     "dynamic" : "false", 
     "properties" : { 
      "content" : { 
      "type" : "string", 
      "fields" : { 
       "content_en" : { 
       "type" : "string", 
       "analyzer" : "english" 
       } 
      } 
      }, 
      "id" : { 
      "type" : "long" 
      }, 
      "title" : { 
      "type" : "string", 
      "fields" : { 
       "title_en" : { 
       "type" : "string", 
       "analyzer" : "english" 
       } 
      } 
      }, 
      "user_id" : { 
      "type" : "long" 
      } 
     } 
     } 
    }, 
    "settings" : { 
     "index" : { 
     "creation_date" : "1438642440687", 
     "number_of_shards" : "5", 
     "number_of_replicas" : "1", 
     "version" : { 
      "created" : "1070099" 
     }, 
     "uuid" : "45vkIigXSCyvHN6g-w5kkg" 
     } 
    }, 
    "warmers" : { } 
    } 
} 

Когда я делаю поиск для killing, слово в содержании, результаты поиска возвращают, как ожидалось.

http://localhost:9200/test_blocks/_search?q=killing&pretty=1 


{ 
    "took" : 1, 
    "timed_out" : false, 
    "_shards" : { 
    "total" : 5, 
    "successful" : 5, 
    "failed" : 0 
    }, 
    "hits" : { 
    "total" : 2, 
    "max_score" : 0.07431685, 
    "hits" : [ { 
     "_index" : "test_blocks", 
     "_type" : "block", 
     "_id" : "218", 
     "_score" : 0.07431685, 
     "_source":{"block":{"id":218,"title":"The \u003ci\u003eparticle\u003c/i\u003e streak","content":"Barry Allen is a Central City police forensic scientist\n      with a reasonably happy life, despite the childhood\n      trauma of a mysterious red and yellow being killing his\n      mother and framing his father. All that changes when a\n      massive \u003cb\u003eparticle\u003c/b\u003e accelerator accident leads to Barry\n      being struck by lightning in his lab.","user_id":82}} 
    }, { 
     "_index" : "test_blocks", 
     "_type" : "block", 
     "_id" : "219", 
     "_score" : 0.07431685, 
     "_source":{"block":{"id":219,"title":"The \u003ci\u003eparticle\u003c/i\u003e streak","content":"Barry Allen is a Central City police forensic scientist\n      with a reasonably happy life, despite the childhood\n      trauma of a mysterious red and yellow being killing his\n      mother and framing his father. All that changes when a\n      massive \u003cb\u003eparticle\u003c/b\u003e accelerator accident leads to Barry\n      being struck by lightning in his lab.","user_id":83}} 
    } ] 
    } 
} 

Однако, учитывая, что у меня есть english анализатор для содержимого поля (content_en), я бы ожидал, что это вернуть мне один и тот же документ для запроса kill. Но это не так. Я получаю 0 хитов.

http://localhost:9200/test_blocks/_search?q=kill&pretty=1 

{ 
    "took" : 1, 
    "timed_out" : false, 
    "_shards" : { 
    "total" : 5, 
    "successful" : 5, 
    "failed" : 0 
    }, 
    "hits" : { 
    "total" : 0, 
    "max_score" : null, 
    "hits" : [ ] 
    } 
} 

Мое понимание по этому анализу запроса является то, что «убийство» был бы сломалась вниз, чтобы «убить»

http://localhost:9200/_analyze?analyzer=english&text=killing 

{ 
    "tokens" : [ { 
    "token" : "kill", 
    "start_offset" : 0, 
    "end_offset" : 7, 
    "type" : "<ALPHANUM>", 
    "position" : 1 
    } ] 
} 

Так почему же не запрос «убить» сопрягать этот документ? Являются ли мои сопоставления неверными или это мой поиск неверен?

Я использую elasticsearch v1.7.0

ответ

2

Вы должны использовать fuzzysearch (несколько вводных доступны here):

curl -XPOST 'http://localhost:9200/test_blocks/_search' -d ' 
{ 
    "query": { 
    "match": { 
     "title": { 
     "query": "kill", 
     "fuzziness": 2, 
     "prefix_length": 1 
     } 
    } 
    } 
}' 

UPD. Имея content_en поле с содержанием, которое было дано по стеммеру, это имеет смысл, на самом деле это поле запроса:

curl -XPOST 'http://localhost:9200/test_blocks/_search' -d ' 
{ 
    "query": { 
    "multi_match": { 
     "type": "most_fields", 
     "query": "kill", 
     "fields": ["block.title", "block.title.title_en"] 
    } 
    } 
}' 
+0

Но английский анализатор я использую уже есть стеммер встроенный, в котором должны быть изменено убийством, чтобы убить. Это неверное предположение? –

+0

Ах, ты прав. Обновлен мой ответ с примером запроса, который фактически использовал бы поле, которое использует ваш стебельщик. – EugZol

+0

Я тестировал с '' полями: ["title", "title.title_en", "content", "content.content_en"] ', но все равно никаких хитов. Что-нибудь еще я делаю неправильно? Что еще я должен смотреть? –

1

Следующие запросы http://localhost:9200/_search?q=kill., http://localhost:9200/_search?q=kill. в конечном итоге поиск через поля _all.

_all поле использует анализатор по умолчанию, который, если переопределен не случается, стандартный анализатор и не английский анализатор.

Для изготовления вышеуказанной работы запроса вам потребуется добавить английский анализатор _all поля и Переиндексирование Пример:

{ 
     "mappings": { 
     "block": { 
      "_all" : {"analyzer" : "english"} 
     } 
    } 

Также хотел бы отметить, отображение в ОП, кажется, не согласуется с структура документа. Как @EugZol отметил наше содержание находится в пределах блока объекта поэтому отображение должно быть что-то на этих линиях:

{ 
    "mappings": { 
    "block": { 
     "properties": { 
     "block": { 
      "properties": { 
      "content": { 
       "type": "string", 
       "analyzer": "standard", 
       "fields": { 
       "content_en": { 
        "type": "string", 
        "analyzer": "english" 
       } 
       } 
      }, 
      "id": { 
       "type": "long" 
      }, 
      "title": { 
       "type": "string", 
       "analyzer": "standard", 
       "fields": { 
       "title_en": { 
        "type": "string", 
        "analyzer": "english" 
       } 
       } 
      }, 
      "user_id": { 
       "type": "long" 
      } 
      } 
     } 
     } 
    } 
    } 
} 
+0

Спасибо за ответ keety. Это имеет смысл, что он использует '_all'. Структура документа была сформирована через жемчужину elasticsearch-rails. Я не указал параметр «dynamic: false», и это привело к тому, что структура выглядела так. Я обновил отображение. Взгляни, пожалуйста. Но теперь даже «убийство» не возвращает никаких хитов. В то время как 'http: // localhost: 9200/test_blocks/_search? Pretty = 1' возвращает документы с содержимым,' http: // localhost: 9200/test_blocks/_search? Q = killing & pretty = 1' не получает хитов. Это прямой термин. Любая помощь приветствуется. –

+0

@RanhiruCooray, основанный на структуре документа OP, выглядит как * _source ": {" block ": {" id ": 219," title ":" The "} *, и в этом случае отображение в OP не корректно. есть объект * block * внутри * block *, как в ответе. Причина, по которой вы не получаете никаких результатов, заключается в том, что динамическое значение false и документ не соответствует сопоставлению, поэтому поля в документах не индексируются только как хранимые. – keety

+0

Также после исправления сопоставления вам нужно выполнить запрос ** localhost: 9200/test_blocks? Q = block.content.content_en% 3Akill & pretty = 1 ** ie query vs * block.content.content_en *, а не * _all * поле – keety

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