2015-09-08 4 views
9

Я пытаюсь создать автозаполнение с использованием mongoosastic и Elastic Search, и до сих пор я смог создать его с помощью смысла, но у меня возникли проблемы с переносом его на mongoosastic.Использование mongoosastic для автозаполнения

Я последовал this учебник от ElasticSearch документации, и я смог добиться того, что я хотел использовать «чувство» с отображением, который выглядит следующим образом:

PUT storys/story/_mapping 
{ 
    "story" : { 
     "properties": { 
      "description": { 
       "type": "string" 
      }, 
      "title": { 
       "type" : "completion", 
       "index_analyzer": "simple", 
       "search_analyzer": "simple" 
      } 
     } 
    } 
} 

и запрос, как это:

GET storys/_suggest 
{ 
    "story-suggest": { 
     "text": "bow", 
     "completion": { 
      "field": "title" 
     } 
    } 
} 

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

var StorySchema = new Schema({ 
     title:{ 
      type: String, es_type:'completion', es_index_analyzer: 'simple', es_search_analyzer: 'simple', es_payloads: true 
     }, 
     description: { 
      type: String 
     } 
    }); 

StorySchema.plugin(mongoosastic); 

И при запросе от контроллера сервера:

Story.search({ 
    query: { 
     "match": { title : req.query.q } 
    }, 
    suggest: { 
      "my-title-suggestions-1" :{ 
       text: req.query.q, 
       completion: { 
        field: 'title' 
       } 
      } 
     } 
}); 

Я понимаю, что когда я использую «чувство», я использую _suggest конечной точки, и именно поэтому Выполняется запрос «рассказ-предложение». Однако, при использовании mongoosastic, я ограничусь использованием .search ({}) для запроса, который действует как _search, я полагаю. Однако я не могу найти способ выполнить поведение _suggest, которое я ищу для автозаполнения, и я продолжаю получать ошибки в ElasticSearch, когда пытаюсь сделать запрос с предложением.

Есть ли способ выполнить то, что я пытаюсь сделать либо с помощью монгоосастического, либо эластичного поиска?

Я пытался делать это, используя «чувство», но даже если я получаю предложения для «автозаполнения» Я также получаю кучу SearchParseExceptions:

GET _search 
{ 
    "query": { 
     "match": { title : "bow" } 
    }, 
    "suggest": { 
     "story-suggest": { 
      "text": "bow", 
      "completion": { 
       "field": "title" 
      } 
     } 
    } 
} 

ответ

11

Здесь представляет собой комплексное решение для базового автозаполнения:

  1. Добавьте необходимые параметры в вашей схеме:

    var TagSchema = new Schema({ 
        name: { 
         type: String, 
         unique: true, 
         required: true, 
         es_type: 'completion', 
         es_index_analyzer: 'simple', 
         es_search_analyzer: 'simple', 
         es_payloads: true 
        } 
    }); 
    
  2. A д.д. плагин для вашей схемы и создать модель:

    TagSchema.plugin(mongoosastic); 
    var Tag = mongoose.model('Tag', TagSchema); 
    
  3. Используйте метод создания отображения, чтобы зарегистрировать отображение с ES.Если вы не сделаете этого шага ваш индекс будет регистрироваться с невыполнением, когда первый документ создается и индексируемой:

    Tag.createMapping(function(err, mapping) { 
        if (err) { 
         console.log('error creating mapping (you can safely ignore this)'); 
         console.log(err); 
        } else { 
         console.log('mapping created!'); 
         console.log(mapping); 
        } 
    }); 
    
  4. * Дополнительно - индекс существующих документов в базе данных:

    var stream = Tag.synchronize(), 
        count = 0; 
    
    stream.on('data', function(err, doc) { 
        count++; 
    }); 
    stream.on('close', function() { 
        console.log('indexed ' + count + ' documents!'); 
    }); 
    stream.on('error', function(err) { 
        console.log(err); 
    }); 
    
  5. Поиск с пустым телом запроса и поставкой двух параметров - 1) Используйте запрос ES suggest, который использует поле «es_completion», которое мы создали в нашей схеме; 2) size = 0, так что теги не возвращаются пустым запросом тела.

    Tag.search(null, { 
        suggest: { 
         "tag-suggest": { 
          "text": "aTermToAutocomplete", 
          "completion": { 
           "field": "name" 
          } 
         } 
        }, 
        "size" : 0 
    }, 
    function(err, results) { 
        if (err) { 
         return console.log(JSON.stringify(err, null, 4)); 
        } 
        return console.log(JSON.stringify(results, null, 4)); 
    }); 
    
1

Я нашел способ. С последним обновлением mongoosastic библиотеки вы можете просто сделать что-то вроде этого:

GET _search 
{ 
    "query": { 
     "match_all": {} 
    }, 
    "suggest": { 
     "story-suggest": { 
      "text": "bow", 
      "completion": { 
       "field": "title" 
      } 
     } 
    } 
} 

Это происходит потому, что новая версия поддерживает mongoosastic suggesters. Просто знайте, что вы делаете, особенно в части запроса, поскольку «match_all» будет соответствовать всем документам и дать вам излишне большой ответ; но все, что вы разместите в «текстовой» части вашего экзаменатора, вернет вам слова для автозаполнения.

Также следует помнить, что для того, чтобы это работало, необходимо использовать метод createMapping в вашем определении модели, как это:

var StorySchema = new Schema({ 
    title:{ 
     type: String, es_type:'completion', es_index_analyzer: 'simple', es_search_analyzer: 'simple', es_payloads: true 
    }, 
    description: { 
     type: String 
    } 
}); 

StorySchema.plugin(mongoosastic); 
var Story = mongoose.model('Story', StorySchema); 

Story.createMapping({}, function(err, mapping){ 
    // ... 
}); 
Смежные вопросы