1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

vuejsでsuggestフォームを作る3

Last updated at Posted at 2019-08-23

前回はDockerにElasticsearchの環境をつくるところまで進めました
第3回目はElasticsearchにテストデータを用意するところまでです

やりたいことのおさらい

キーワードを入力していくとキーワード候補エリア、関連エリア(もしかして、、、これ?みたいな)が表示されるやつを作ります

テストデータを用意

サジェストできそうなデータを用意していきます

クジラ飛行机さんがパブリックドメインで公開してくれている英和辞書データを使います。
ありがとうございます。
https://github.com/kujirahand/EJDict

1.templateを作成

こちらは以下の記事を参考にして作成していきます
Elasticsearch 日本語の為のスキーマレス環境構築

{
  "template": "ejdict",
  "settings": {
    "number_of_shards" : 1,
    "number_of_replicas" : 0,
    "analysis": {
      "filter": {
        "romaji": {
          "type": "kuromoji_readingform",
          "use_romaji": false
        }
      },
      "tokenizer": {
        "kuromoji_search_tokenizer": {
          "type": "kuromoji_tokenizer",
          "mode": "search"
        },
        "forward_match_tokenizer": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 30,
          "token_chars": [
            "letter",
            "digit"
          ]
        },
        "include_match_tokenizer": {
          "type": "nGram",
          "min_gram": 2,
          "max_gram": 15,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      },
      "analyzer": {
        "kuromoji_search_analyzer": {
          "type": "custom",
          "char_filter": [
            "html_strip",
            "kuromoji_iteration_mark"
          ],
          "tokenizer": "kuromoji_search_tokenizer",
          "filter": [
            "cjk_width",
            "lowercase",
            "kuromoji_stemmer",
            "kuromoji_part_of_speech",
            "romaji"
          ]
        },
        "include_match_analyzer": {
          "type": "custom",
          "char_filter": ["html_strip"],
          "tokenizer": "include_match_tokenizer",
          "filter": ["cjk_width", "lowercase"]
        },
        "forward_match_analyzer": {
          "type": "custom",
          "char_filter": [
            "html_strip"
          ],
          "tokenizer": "forward_match_tokenizer"
        }
      }
    }
  },
  "mappings": {
    "_doc": {
      "dynamic_templates": [
        {
          "word_field": {
            "match": "word",
            "match_pattern": "regex",
            "match_mapping_type": "string",
            "mapping": {
              "type": "text",
              "fields": {
                "raw": {
                  "type": "keyword"
                },
                "include_match": {
                  "type": "text",
                  "analyzer": "include_match_analyzer"
                },
                "forward_match": {
                  "type": "text",
                  "analyzer": "forward_match_analyzer"
                }
              }
            }
          }
        },
        {
          "meaning_field": {
            "match": "meaning",
            "match_pattern": "regex",
            "match_mapping_type": "string",
            "mapping": {
              "type": "text",
              "fields": {
                "raw": {
                  "type": "keyword"
                },
                "ja_search": {
                  "type": "text",
                  "analyzer": "kuromoji_search_analyzer"
                },
                "include_match": {
                  "type": "text",
                  "analyzer": "include_match_analyzer"
                },
                "forward_match": {
                  "type": "text",
                  "analyzer": "forward_match_analyzer"
                }
              }
            }
          }
        }
      ]
    }
  }
}

前方一致、include検索ができるようにmulti fieldを定義しています
(うまく検索できるかはサジェストフォームを作成しながら検証していきます。一旦これで)

2.templateを登録

特にスクリプトを用意する必要はないのですが、
コマンド実行を覚えられないのでスクリプトを作ります

# !/bin/bash
set -eu

if [ ! -d EJDict ]; then
  git clone https://github.com/kujirahand/EJDict
fi

echo "init template...."
base_root=$(cd $(dirname $0); pwd)
template_path=${base_root}/ejdict_template.json
curl -H "Content-Type: application/json" -XPUT "http://localhost:9200/_template/ejdic_template?pretty" -d @$template_path

3.importプログラムを作成

ejdictインデックスにword、meaningフィールドを作成します

import.js
const fs = require('fs');
const request = require('request');
const readline = require("readline-promise").default
const async = require('async');

var importQueue = async.queue(function (opt, callback) {

  const line = opt.line
  const index = opt.index
  const splitLine= line.split("¥t");

  console.log(`add index.....${index}`)

  new Promise((resolve, reject) => {
    try {

      const headers = {
        'Content-Type':'application/json'
      }
      const postData = JSON.stringify({
        "id": index,
        "word": splitLine[0],
        "meaning": splitLine[1]
      });
      const options = {
        url: 'http://localhost:9200/ejdict/_doc/' + index,
        method: 'POST',
        headers: headers,
        body: postData,
      }
      request(options, function (error, response, body) {
        if (error) reject()
        callback(null);
      })
    } catch (e) {
      console.log(e);
      reject();
    }
  });

}, 100);

(async function () {
  try {

    const rlp = readline.createInterface({
      terminal: false,
      input: fs.createReadStream('./EJDict/release/ejdic-hand-utf8.txt')
    });
    rlp.forEach((line, index) => {
      importQueue.push({line:line, index:index});
    });

  } catch (e) {
    console.error(e);
  }
})()

実行します

% node import.js

リクエストしてみます

% curl -H "Content-Type: application/json" -XGET "http://localhost:9200/ejdict/_search?pretty"  

辞書データが登録されていますね

{
  "took" : 22,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2304,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "ejdict",
        "_type" : "_doc",
        "_id" : "0",
        "_score" : 1.0,
        "_source" : {
          "id" : 0,
          "word" : "'em",
          "meaning" : "=them"
        }
      },

次回はいよいよサジェストフォームを作っていく予定です

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?