Я новичок в Elasticsearch, и я потратил несколько часов, пытаясь решить эту проблему, поэтому заранее спасибо, если вы попытаетесь мне помочь.
:) (Не слишком) Краткое пояснение: (Что у меня есть на данный момент и чего я пытаюсь достичь):
Я создал базу данных CouchDB (spain_locales), которая содержит более 8000 документов с испанскими городами и провинциями. С другой стороны, у меня есть HTML-форма с автозаполнением jQuery, и я показываю результаты по мере ввода. Я подключаюсь к ElasticSearch из созданного мной PHP (поставщика услуг Laravel) и возвращаю результаты для автозаполнения jQuery. Я предполагаю, что это можно сделать, подключившись с клиента напрямую к ElasticSearch, но из соображений безопасности я пока предпочитаю, чтобы это было так.
:( Проблема:
Результаты, которые я получаю от ElasticSearch, не совсем то, что я ожидаю, и я не знаю, как исправить то, что у меня есть, и правильно ли это сделать. Я не знаю, нужен ли логический запрос для того, что мне нужно, или мне следует использовать другой тип запроса.
Я получаю результаты только в том случае, если я набираю слова точно так же, как они есть в базе данных:
Если я набираю Алава, я получаю результаты, но НЕ для Алава (имеет значение акцент Á)
Я не получаю результатов, пока не наберу полное слово:
Если я наберу Albacete, я получу результаты, но НЕ для Albacet.
Я использовал плагин CouchDB River для ElasticSearch для синхронизации CouchDB с ElasticSearch ›› https://github.com/elasticsearch/elasticsearch-river-couchdb, и я сделал это с помощью следующей команды через терминал:
curl -XPUT 'localhost:9200/_river/spain_locales/_meta' -d '{
"type" : "couchdb",
"couchdb" : {
"host" : "localhost",
"port" : 5984,
"db" : "spain_locales",
"filter" : null
},
"index" : {
"index" : "spain_locales",
"type" : "spain_locales",
"bulk_size" : "100",
"bulk_timeout" : "10ms"
}
}'
Я также пробовал с:
curl -XPUT 'localhost:9200/_river/spain_locales/_meta' -d '{
"type" : "couchdb",
"couchdb" : {
"host" : "localhost",
"port" : 5984,
"db" : "spain_locales",
"filter" : null
},
"index" : {
"number_of_shards" : 2,
"refresh_interval" : "1s",
"analysis": {
"analyzer": {
"folding": {
"tokenizer": "standard",
"filter": [ "lowercase", "asciifolding" ]
}
}
},
"index" : "spain_locales",
"type" : "spain_locales",
"bulk_size" : "100",
"bulk_timeout" : "10ms"
}
}'
Ни одно из вышеперечисленных не возвращает никаких ошибок и успешно не создает синхронизацию _river, но по-прежнему имеет проблемы с акцентами и целыми словами.
Я также попытался каким-то образом применить необходимые фильтры с помощью следующей команды через терминал:
curl -XPUT 'localhost:9200/spain_locales/' -d '
{
"settings": {
"analysis": {
"analyzer": {
"folding": {
"tokenizer": "standard",
"filter": [ "lowercase", "asciifolding" ]
}
}
}
},
"uuid":"KwKrBc3uQoG5Ld1nOdc5rQ"
}'
Но я получаю следующую ошибку:
{"error":"IndexAlreadyExistsException[[spain_locales] already exists]","status":400}
Примеры документов CouchDB:
{
"_id": "1",
"_rev": "1-087ddbe8593f68f1d7d37a9c3f6de787",
"Provincia": "Álava",
"Poblacion": "Alegría-Dulantzi",
"helper": ""
}
{
"_id": "10",
"_rev": "1-ce38dcdabeb3b34d34d2296c6e2fdf24",
"Provincia": "Álava",
"Poblacion": "Ayala/Aiara",
"helper": ""
}
{
"_id": "100",
"_rev": "1-72e66601e378ee48519aa93601dc0717",
"Provincia": "Albacete",
"Poblacion": "Herrera (La)",
"helper": "La Herrera"
}
Поставщик/контроллер услуг PHP:
public function searchzones(){
$q = (Input::has('term')) ? Input::get('term') : 'null';
$params['index'] = 'spain_locales';
$params['type'] = 'spain_locales';
$params['body']['query']['bool']['should'] = array(
array('match' => array('Poblacion' => $q)),
array('match' => array('Provincia' => $q))
);
$query = $this->elasticsearch->search($params);
if ($query['hits']['total'] >= 1){
$results = $query['hits']['hits'];
foreach ($results as $zone) {
$databag[] = array( "value" => $zone['_source']['Poblacion'].', '.$zone['_source']['Provincia'],
"state" => $zone['_source']['Provincia'],
"city" => $zone['_source']['Poblacion'],
);
}
} else {
$results = ['res' => null];
$databag[] = array();
}
return $databag;
} // End Search Zones
jQuery (JavaScript):
// Sugest locations when user type in zones
$(document).ready(function() {
$('#zones').autocomplete({
source : applink + 'ajax/searchzones',
select : function(event, ui){
console.log(ui);
}
}); // End autocomplete
}); // End Document ready
Часть HTML-формы (Twitter Bootstrap):
<div class="form-group">
<div class="input-group input-append dropdown">
<input type="text" class="form-control typeahead" placeholder="City name" name="zones" id="zones">
<div class="input-group-btn" >
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
<ul class="dropdown-menu dropdown-menu-right" id="dropZonesAjax">
</ul>
</div>
</div>
<div id="zonesAjax"></div>
</div>
Я нашел следующий ресурс: http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/asciifolding-token-filter.html, но я не знаю, как это реализовать/достичь.
Большое спасибо за ваше время и за попытку помочь! Извините за мой английский!