node vue 实时推送_如何使用Node,Vue和ElasticSearch构建实时搜索引擎

本教程详细介绍了如何利用Node.js、Vue.js和Elasticsearch构建一个实时搜索引擎。首先设置环境,安装所需库,接着在Elasticsearch中创建索引并添加数据。然后,使用Express服务创建网页,并实现客户端搜索功能。通过这个过程,你可以了解到如何将Elasticsearch与前端框架结合,实现数据的实时检索。
摘要由CSDN通过智能技术生成

node vue 实时推送

介绍 (Introduction)

Elasticsearch is a distributed, RESTful search and analytics engine capable of solving a growing number of use cases. Elasticsearch is built on top of Apache Lucene, which is a high-performance text search engine library.

Elasticsearch是一个分布式的RESTful搜索和分析引擎,能够解决越来越多的用例。 Elasticsearch建立在Apache Lucene之上, Apache Lucene是一个高性能的文本搜索引擎库。

In this tutorial, you will build a real-time search engine using Node.js, Elasticsearch, and Vue.js. As a result, a basic comprehension of Vue.js and Node.js (Express) is needed to follow this tutorial.

在本教程中,您将使用Node.js ,Elasticsearch和Vue.js构建一个实时搜索引擎。 因此,需要基本的Vue.js和Node.js(Express)理解才能遵循本教程。

第1步-准备环境 (Step 1 — Preparing the Environment)

Let’s get started with setting up the environment for this lesson. Since you will use Node.js, the easiest way to get started is to create a new folder and run npm init. Create a new folder called elastic-node, change directory into the new folder and then run npm init:

让我们开始设置本课的环境。 由于将使用Node.js,因此最简单的入门方法是创建一个新文件夹并运行npm init 。 创建一个名为elastic-node的新文件夹,将目录更改为新文件夹,然后运行npm init

Create a new directory called elastic-node:

创建一个名为elastic-node的新目录:

  • mkdir elastic-node

    mkdir弹性节点

Move into the new folder:

移至新文件夹:

  • cd elastic-node

    cd弹性节点

Run npm init to create a package.json file:

运行npm init创建一个package.json文件:

  • npm init

    npm初始化

The above commands take you through the process of creating a package.json file, which is required to run any Node.js library.

上面的命令将带您完成创建package.json文件的过程,这是运行任何Node.js库所必需的。

Next, you need to install libraries that will be needed for the real-time search engine. Install the libraries with the following command:

接下来,您需要安装实时搜索引擎所需的库。 使用以下命令安装库:

  • npm install express body-parser elasticsearch

    npm install express正文解析器elasticsearch

The express library will run the server, while the body-parser library works with express to parse body requests. elasticsearch is the official Node.js library for Elasticsearch, which is the engine on which the real-time search will be built.

express库将运行服务器,而body-parser库与express一起使用以解析主体请求。 elasticsearch是Elasticsearch的官方Node.js库,该库是构建实时搜索的引擎。

Now the first part of your environment is set up. However, Elasticsearch itself is missing from your setup. You will need to install Elasticsearch which can be done in a few different ways. If you are using a Debian Linux operating system, you can just download the .deb file and install using dpkg.

现在,您的环境的第一部分已设置完毕。 但是,您的设置中缺少Elasticsearch本身。 您将需要安装Elasticsearch,这可以通过几种不同的方式完成。 如果您使用的是Debian Linux操作系统,则只需下载.deb文件并使用dpkg安装。

Run the following command to download the .deb file:

运行以下命令以下载.deb文件:

  • curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.6.4.deb

    curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.6.4.deb

Now install the deb package using dpkg:

现在使用dpkg安装deb软件包:

  • sudo dpkg -i elasticsearch-5.6.4.deb

    须藤dpkg -i elasticsearch-5.6.4.deb

For other distributions/operating systems, you can find a guide on how to install Elasticsearch here.

对于其他发行版/操作系统,您可以在此处找到有关如何安装Elasticsearch的指南。

Elasticsearch is not started automatically after installation. Elasticsearch can be started and stopped using the service command.

安装后,Elasticsearch不会自动启动。 可以使用service命令启动和停止Elasticsearch。

Run the following to start the elasticsearch service:

运行以下命令以启动elasticsearch服务:

  • sudo -i service elasticsearch start

    sudo -i服务elasticsearch开始

You can stop the elasticsearch service with this command:

您可以使用以下命令停止elasticsearch服务:

  • sudo -i service elasticsearch stop

    sudo -i服务elasticsearch停止

To configure Elasticsearch to start automatically when the system boots up, run this to reload the systemctl daemon:

要将Elasticsearch配置为在系统启动时自动启动,请运行以下命令以重新加载systemctl守护程序:

  • sudo /bin/systemctl daemon-reload

    须藤/ bin / systemctl守护进程重新加载

Then enable elasticsearch so it can be called as a service:

然后启用elasticsearch以便可以将其称为服务:

  • sudo /bin/systemctl enable elasticsearch.service

    sudo / bin / systemctl启用elasticsearch.service

After running the command above, you can start Elasticsearch with this command:

运行上述命令后,您可以使用以下命令启动Elasticsearch:

  • sudo systemctl start elasticsearch.service

    sudo systemctl启动elasticsearch.service

Stop it with the following:

使用以下命令停止它:

  • sudo systemctl stop elasticsearch.service

    sudo systemctl停止elasticsearch.service

You can also check the status of Elasticsearch:

您还可以检查Elasticsearch的状态:

  • sudo service elasticsearch status

    sudo服务elasticsearch状态

第2步—在Elasticsearch中索引数据 (Step 2 — Indexing Data in Elasticsearch)

Create a data.js file in your root folder and add the following code:

在您的根文件夹中创建一个data.js文件,并添加以下代码:

data.js
data.js
//require the Elasticsearch librray
const elasticsearch = require('elasticsearch');
// instantiate an Elasticsearch client
const client = new elasticsearch.Client({
   hosts: [ 'http://localhost:9200']
});
// ping the client to be sure Elasticsearch is up
client.ping({
     requestTimeout: 30000,
 }, function(error) {
 // at this point, eastic search is down, please check your Elasticsearch service
     if (error) {
         console.error('Elasticsearch cluster is down!');
     } else {
         console.log('Everything is ok');
     }
 });

This code first requires the Elasticsearch library and then sets up a new Elasticsearch client, passing in an array of a host, http://localhost:9200. This is because, by default, Elasticsearch listens on :9200. Next, you ping the Elasticsearch client to be sure the server is up. If you run node data.js, you will get a message that says Everything is ok.

此代码首先需要Elasticsearch库,然后设置一个新的Elasticsearch客户端,并传入一个主机数组http://localhost:9200 。 这是因为,默认情况下,Elasticsearch监听:9200 。 接下来,您对Elasticsearch客户端执行ping操作,以确保服务器已启动。 如果运行node data.js ,将收到一条消息,指出“ Everything is ok

步骤3 —了解索引 (Step 3 — Understanding Indexes)

Unlike normal databases, an Elasticsearch index is a place to store related documents. For example, you will create an index called scotch.io-tutorial to store data of type cities_list. This is how it’s done in Elasticsearch: 

与普通数据库不同,Elasticsearch索引是存储相关文档的地方。 例如,您将创建一个名为scotch.io-tutorial的索引来存储“ cities_list ”类型的数据。 这是在Elasticsearch中完成的方式:

data.js
data.js
// create a new index called scotch.io-tutorial. If the index has already been created, this function fails safely
client.indices.create({
      index: 'scotch.io-tutorial'
  }, function(error, response, status) {
      if (error) {
          console.log(error);
      } else {
          console.log("created a new index", response);
      }
});

Add this piece of code after the ping function you had written before. Now, run node data.js again. You will get two messages:

在您之前编写的ping函数之后添加这段代码。 现在,再次运行node data.js 。 您将收到两条消息:

  • Everything is okay

    Everything is okay

  • Created a new index (with the response from Elasticsearch)

    Created a new index (来自Elasticsearch的响应)

步骤4 —将文档添加到索引 (Step 4 — Adding Documents To Indexes)

You can add documents to preexisting indexes with the Elasticsearch API. To do this, use the following code:

您可以使用Elasticsearch API将文档添加到预先存在的索引中。 为此,请使用以下代码:

// add a data to the index that has already been created
client.index({
     index: 'scotch.io-tutorial',
     id: '1',
     type: 'cities_list',
     body: {
         "Key1": "Content for key one",
         "Key2": "Content for key two",
         "key3": "Content for key three",
     }
 }, function(err, resp, status) {
     console.log(resp);
 });

The body refers to the document you want to add to the scotch.io-tutorial index, while the type is more of a category. However, note that if the id key is omitted, Elasticsearch will auto-generate one.

body是指您要添加到scotch.io-tutorial索引中的文档,而类型更多是类别。 但是,请注意,如果省略id密钥,Elasticsearch将自动生成一个。

In this tutorial, your document will be a list of all the cities in the world. If you are to add each city one by one, it can take days to index them all. Luckily, Elasticsearch has a bulk function that can process bulk data.

在本教程中,您的文档将是世界上所有城市的列表。 如果要逐个添加每个城市,则可能需要几天的时间才能对所有城市建立索引。 幸运的是,Elasticsearch具有可以处理批量数据的bulk功能。

First, grab the JSON file containing all cities in the world here and save that into your root folder as cities.json.

首先,在此处获取包含世界上所有城市的JSON文件,并将其保存到根文件夹中,并cities.jsoncities.json

It’s time to use the bulk API to import the large dataset:

现在该使用bulk API导入大型数据集了:

data.js
data.js
// require the array of cities that was downloaded
const cities = require('./cities.json');
// declare an empty array called bulk
var bulk = [];
//loop through each city and create and push two objects into the array in each loop
//first object sends the index and type you will be saving the data as
//second object is the data you want to index
cities.forEach(city =>{
   bulk.push({index:{ 
                 _index:"scotch.io-tutorial", 
                 _type:"cities_list",
             }          
         })
  bulk.push(city)
})
//perform bulk indexing of the data passed
client.bulk({body:bulk}, function( err, response  ){ 
         if( err ){ 
             console.log("Failed Bulk operation".red, err) 
         } else { 
             console.log("Successfully imported %s".green, cities.length); 
         } 
});

Here, you have looped through all the cities in your JSON file, and at each loop, you append an object with the index and type of the document you will be indexing. There are two pushes to the array in the loop because the bulk API expects an object containing the index definition first, and then the document you want to index. For more information on that, you can check out this article.

在这里,您已经遍历了JSON文件中的所有城市,并且在每个循环中,都为对象附加了将要建立索引的文档的indextype 。 循环中需要两次推送到数组,因为bulk API要求首先包含索引定义的对象,然后是要索引的文档。 有关更多信息,您可以查看本文

Next, you called the client.bulk function, passing in the new bulk array as the body. This indexes all your data into Elasticsearch with the index of scotch.io-tutorial and type cities_list.

接下来,您调用了client.bulk函数,并传入了新的批量数组作为主体。 这会使用scotch.io-tutorial的索引scotch.io-tutorial您的所有数据索引到Elasticsearch中,并键入cities_list

第5步-使用Express服务到达网页 (Step 5 — Using Express to Serve the Landing Page)

Your Elasticsearch instance is up and running, and you can connect with it using Node.js. It’s time to use Express to serve a landing page and use the setup you have running so far.

您的Elasticsearch实例已启动并正在运行,您可以使用Node.js与之连接。 现在是时候使用Express服务着陆页并使用您到目前为止运行的设置了。

Create a file called index.js and add the following code:

创建一个名为index.js的文件,并添加以下代码:

index.js
index.js
//require the Elasticsearch librray
const elasticsearch = require('elasticsearch');
// instantiate an elasticsearch client
const client = new elasticsearch.Client({
   hosts: [ 'http://localhost:9200']
});
//require Express
const express = require( 'express' );
// instanciate an instance of express and hold the value in a constant called app
const app     = express();
//require the body-parser library. will be used for parsing body requests
const bodyParser = require('body-parser')
//require the path library
const path    = require( 'path' );

// ping the client to be sure Elasticsearch is up
client.ping({
     requestTimeout: 30000,
 }, function(error) {
 // at this point, eastic search is down, please check your Elasticsearch service
     if (error) {
         console.error('elasticsearch cluster is down!');
     } else {
         console.log('Everything is ok');
     }
 });


// use the bodyparser as a middleware  
app.use(bodyParser.json())
// set port for the app to listen on
app.set( 'port', process.env.PORT || 3001 );
// set path to serve static files
app.use( express.static( path.join( __dirname, 'public' )));
// enable CORS 
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

// defined the base route and return with an HTML file called tempate.html
app.get('/', function(req, res){
  res.sendFile('template.html', {
     root: path.join( __dirname, 'views' )
   });
})

// define the /search route that should return elastic search results 
app.get('/search', function (req, res){
  // declare the query object to search elastic search and return only 200 results from the first result found. 
  // also match any data where the name is like the query string sent in
  let body = {
    size: 200,
    from: 0, 
    query: {
      match: {
          name: req.query['q']
      }
    }
  }
  // perform the actual search passing in the index, the search query and the type
  client.search({index:'scotch.io-tutorial',  body:body, type:'cities_list'})
  .then(results => {
    res.send(results.hits.hits);
  })
  .catch(err=>{
    console.log(err)
    res.send([]);
  });

})
// listen on the specified port
app .listen( app.get( 'port' ), function(){
  console.log( 'Express server listening on port ' + app.get( 'port' ));
} );

Looking at the code above, you will see that the code has done the following:

查看上面的代码,您将看到代码已完成以下操作:

  • Required the Express, body-parser and path libraries.

    需要Express,body解析器和路径库。
  • Set a new instance of Express to the constant called app.

    将Express的新实例设置为名为app的常量。

  • Set the app to use the bodyParser middleware.

    将应用程序设置为使用bodyParser中间件。

  • Set the static part of the app to a folder called public. This folder has not been created yet.

    将应用程序的静态部分设置为名为public的文件夹。 此文件夹尚未创建。

  • Defined a middleware which adds CORS header to the app.

    定义了将CORS标头添加到应用程序的中间件。

  • Defined a GET route for the root URL of the app, represented by /. In this route, the code returns a file called template.html which is in the views folder.

    为应用程序的root URL定义了GET路由,以/表示。 在此路由中,代码返回一个位于views文件夹中的名为template.html的文件。

  • Defined a GET route for the /search URL of the app which uses a query object to search for the match of the data passed to it via the query string. The main search query is included within the query object. You can add different search queries to this object. For this query, you add a key with the query and return an object telling it that the name of the document you are looking for should match req.query['q'].

    为应用程序的/search URL定义了GET路由,该路由使用查询对象来搜索通过查询字符串传递给它的数据的匹配项。 主搜索查询包含在查询对象内。 您可以向该对象添加不同的搜索查询。 对于此查询,您可以在查询中添加一个键,并返回一个对象,告诉该对象您要查找的文档名称应与req.query['q']匹配。

Besides the query object, the search body can contain other optional properties, including size and from. The size property determines the number of documents to be included in the response. If this value is not present, by default ten documents are returned. The from property determines the starting index of the returned documents. This is useful for pagination.

除了查询对象之外,搜索主体还可以包含其他可选属性,包括sizefromsize属性确定响应中要包含的文档数。 如果不存在此值,默认情况下将返回十个文档。 from属性确定返回文档的起始索引。 这对于分页很有用。

第6步-了解Search API响应 (Step 6 — Understanding the Search API Response)

If you were to log the response from the search API, it would include a lot of information. Below is an example:

如果您要记录来自搜索API的响应,它将包含很多信息。 下面是一个示例:


   
   
Output
{ took: 88, timed_out: false, _shards: { total: 5, successful: 5, failed: 0 }, hits: { total: 59, max_score: 5.9437823, hits: [ {"_index":"scotch.io-tutorial", "_type":"cities_list", "_id":"AV-xjywQx9urn0C4pSPv", "_score":5.9437823," _source":{"country":"ES","name":"A Coruña","lat":"43.37135","lng":"-8.396"}}, [Object], ... [Object] ] } }

The response includes a took property for the number of milliseconds it took to find the results, timed_out, which is only true if no results were found in the maximum allowed time, _shards for information about the status of the different nodes (if deployed as a cluster of nodes), and hits, which includes the search results.

响应包含一个用于获取结果的毫秒数的took属性, timed_out ,仅当在最大允许时间内未找到结果时才为true, _shards用于获取有关不同节点状态的信息(如果部署为a节点簇)和hits ,其中包括搜索结果。

Within the hits property, you have an object with the following properties:

hits属性中,您有一个具有以下属性的对象:

  • total shows the total number of matched items.

    total显示匹配项的总数。

  • max_score is the maximum score of the found items.

    max_score是找到的项目的最高分。

  • hits is an array that includes the found items.

    hits是一个包含找到的项目的数组。

This is why you returned response.hits.hits in the search route, which houses the documents found.

这就是为什么您在包含找到的文档的搜索路径中返回response.hits.hits原因。

第7步-创建HTML模板 (Step 7 — Creating The HTML Template)

First, create two new folders in your root folder named views and public which were referenced in the previous step. Next, create a file called template.html in the views folder and paste the following code:

首先,在您的根文件夹中创建两个新文件夹,分别是上一步中引用的viewspublic 。 接下来,在views文件夹中创建一个名为template.html的文件,并粘贴以下代码:

template.html
template.html
<!-- template.html -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div class="container" id="app">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1>Search Cities around the world</h1>
        </div>
    </div>
    <div class="row">
        <div class="col-md-4 col-md-offset-3">
            <form action="" class="search-form">
                <div class="form-group has-feedback">
                    <label for="search" class="sr-only">Search</label>
                    <input type="text" class="form-control" name="search" id="search" placeholder="search" v-model="query" >
                    <span class="glyphicon glyphicon-search form-control-feedback"></span>
                </div>
            </form>
        </div>
    </div>
    <div class="row">
        <div class="col-md-3" v-for="result in results">
            <div class="panel panel-default">
                <div class="panel-heading">
                <!-- display the city name and country  -->
                    {{ result._source.name }}, {{ result._source.country }} 
                </div>
                <div class="panel-body">
                <!-- display the latitude and longitude of the city  -->
                    <p>lat:{{ result._source.lat }}, long: {{ result._source.lng }}.</p>
                </div>
            </div>
        </div>
    </div>
</div>
<!--- some styling for the page -->
<style>
    .search-form .form-group {
        float: right !important;
        transition: all 0.35s, border-radius 0s;
        width: 32px;
        height: 32px;
        background-color: #fff;
        box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
        border-radius: 25px;
        border: 1px solid #ccc;
    }

    .search-form .form-group input.form-control {
        padding-right: 20px;
        border: 0 none;
        background: transparent;
        box-shadow: none;
        display: block;
    }

    .search-form .form-group input.form-control::-webkit-input-placeholder {
        display: none;
    }

    .search-form .form-group input.form-control:-moz-placeholder {
        /* Firefox 18- */
        display: none;
    }

    .search-form .form-group input.form-control::-moz-placeholder {
        /* Firefox 19+ */
        display: none;
    }

    .search-form .form-group input.form-control:-ms-input-placeholder {
        display: none;
    }

    .search-form .form-group:hover,
    .search-form .form-group.hover {
        width: 100%;
        border-radius: 4px 25px 25px 4px;
    }

    .search-form .form-group span.form-control-feedback {
        position: absolute;
        top: -1px;
        right: -2px;
        z-index: 2;
        display: block;
        width: 34px;
        height: 34px;
        line-height: 34px;
        text-align: center;
        color: #3596e0;
        left: initial;
        font-size: 14px;
    }
</style>

In the code snippet above, there are two main sections: HTML and CSS code.

在上面的代码段中,有两个主要部分:HTML和CSS代码。

In the HTML section, you required three different libraries:

在HTML部分中,您需要三个不同的库:

  1. Bootstrap CSS for styling the page.

    引导CSS样式页面。
  2. Axios js for making HTTP requests to our server.

    Axios js,用于向我们的服务器发出HTTP请求。
  3. Vue.js which is a minimalistic framework that you will use for the view.

    Vue.js是一个用于视图的简约框架。

In the CSS section you have applied styling to make the search input hide and reveal itself once you hover over the search icon.

在CSS部分中,您将样式应用到鼠标悬停在搜索图标上之后,隐藏并显示搜索输入。

Next, there is an input for the search box that you assigned its v-model to query (this will be used by Vue.js). After this, you looped through all our results.

接下来,为搜索框提供一个输入,您为其分配了其v-model以进行query (Vue.js将使用此输入)。 之后,您遍历了我们所有的结果。

Run the node index.js command and then visit http://localhost:3001/ in a browser. You will see the app’s landing page.

运行node index.js命令,然后在浏览器中访问http://localhost:3001/ 。 您将看到该应用程序的登录页面。

Next, add a script tag in your template.html file:

接下来,在您的template.html文件中添加一个脚本标记:

template.html
template.html
// create a new Vue instance
var app = new Vue({
    el: '#app',
    // declare the data for the component (An array that houses the results and a query that holds the current search string)
    data: {
        results: [],
        query: ''
    },
    // declare methods in this Vue component. here only one method which performs the search is defined
    methods: {
        // make an axios request to the server with the current search query
        search: function() {
            axios.get("http://127.0.0.1:3001/search?q=" + this.query)
                .then(response => {
                    this.results = response.data;

                })
        }
    },
    // declare Vue watchers
    watch: {
        // watch for change in the query string and recall the search method
        query: function() {
            this.search();
        }
    }

})

In this section, you declared a new instance of Vue, mounting it on the element with the id of app. You declared data properties which include query, which you had attached to the search input, and results, which is an array of all results found.

在本节中,您声明了Vue的新实例,并将其安装在idapp的元素上。 您声明了数据属性,其中包括已附加到搜索输入的queryresults ,result是找到的所有结果的数组。

In the methods quota, you have just one function called search, which triggers a GET request to the search route. This passes along the current input in the search box. This in turn returns a response that is then looped in the HTML code block.

methods配额中,只有一个名为search函数,该函数触发对search路径的GET请求。 这沿搜索框中的当前输入。 依次返回一个响应,然后在HTML代码块中循环该响应。

Finally, you use watchers in Vue.js, which performs an action anytime data being watched changes. Here, you are watching for a change in the query data, and once it changes, the search method is fired.

最后,您可以在Vue.js中使用watchers程序,该watchers在监视的数据发生更改时立即执行操作。 在这里,您正在监视query数据中的更改,并且一旦更改,就会触发search方法。

If you re-run the node index.js command now and navigate to http://localhost:3001/ again, it should work as seen:

Completed search app that displays results

如果现在重新运行node index.js命令并再次导航到http://localhost:3001/ ,它应该可以正常运行:

步骤8 —从客户端搜索 (Step 8 — Searching From The Client Side)

If you do not want to send requests to the server every time a search occurs, you can search the Elasticsearch engine from the client side. Some developers might not be comfortable with hitting their servers for every search term, while some feel it’s more secure to search from the server side.

如果不想在每次搜索时都将请求发送到服务器,则可以从客户端搜索Elasticsearch引擎。 有些开发人员可能不愿意为每个搜索词命中服务器,而有些开发人员则认为从服务器端进行搜索更安全。

Elasticsearch offers a browser build which can make searches. This step will guide you through searching from the browser client.

Elasticsearch提供了可以进行搜索的浏览器版本。 此步骤将指导您完成从浏览器客户端的搜索。

First, add a new route to your Express file and restart your server:

首先,将新路由添加到Express文件并重新启动服务器:

index.js
index.js
// decare a new route. This route serves a static HTML template called template2.html
app.get('/v2', function(req, res){
  res.sendFile('template2.html', {
     root: path.join( __dirname, 'views' )
   });
})

In this code block, you created a new route for the URL at /v2 to return a static HTML file called template2.html. You will create this file soon.

在此代码块中,您为/v2处的URL创建了新路由,以返回名为template2.html的静态HTML文件。 您将很快创建此文件。

Next, you need to download the client library for Elasticsearch here. After downloading, extract and copy elasticsearch.min.js to the public folder in your application root.

接下来,您需要在此处下载Elasticsearch的客户端库。 下载后,解压缩elasticsearch.min.js并将其复制到应用程序根目录下的公共文件夹中。

Note: If you encounter CORS issues after connecting to the Elasticsearch engine from the client side, and the following snippet to the end of the Elasticsearch configuration file. You can locate this file by reviewing Elasticsearch’s reference material.

注意:如果从客户端连接到Elasticsearch引擎以及以下代码段到Elasticsearch配置文件末尾后遇到CORS问题。 您可以通过查看Elasticsearch的参考资料来找到此文件。

/etc/elasticsearch/elasticsearch.yml
/etc/elasticsearch/elasticsearch.yml
http.cors.enabled : true
http.cors.allow-origin : "*"

After that is done, restart your Elasticsearch instance:

完成之后,重新启动您的Elasticsearch实例:

  • sudo service elasticsearch restart

    sudo服务elasticsearch重新启动

Next, create a file called template2.html in your views folder and this code:

接下来,在您的views文件夹中创建一个名为template2.html的文件,并使用以下代码:

template2.html
template2.html
<!-- template2.html -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div class="container" id="app">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1>Search Cities around the world</h1>
        </div>
    </div>
    <div class="row">
        <div class="col-md-4 col-md-offset-3">
            <form action="" class="search-form">
                <div class="form-group has-feedback">
                    <label for="search" class="sr-only">Search</label>
                    <input type="text" class="form-control" name="search" id="search" placeholder="search" v-model="query" >
                    <span class="glyphicon glyphicon-search form-control-feedback"></span>
                </div>
            </form>
        </div>
    </div>
    <div class="row">
        <div class="col-md-3" v-for="result in results">
            <div class="panel panel-default">
                <div class="panel-heading">
                <!-- display the city name and country  -->
                    {{ result._source.name }}, {{ result._source.country }} 
                </div>
                <div class="panel-body">
                <!-- display the latitude and longitude of the city  -->
                    <p>lat:{{ result._source.lat }}, long: {{ result._source.lng }}.</p>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="/elasticsearch.min.js"></script>
<style>
    .search-form .form-group {
        float: right !important;
        transition: all 0.35s, border-radius 0s;
        width: 32px;
        height: 32px;
        background-color: #fff;
        box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
        border-radius: 25px;
        border: 1px solid #ccc;
    }

    .search-form .form-group input.form-control {
        padding-right: 20px;
        border: 0 none;
        background: transparent;
        box-shadow: none;
        display: block;
    }

    .search-form .form-group input.form-control::-webkit-input-placeholder {
        display: none;
    }

    .search-form .form-group input.form-control:-moz-placeholder {
        /* Firefox 18- */
        display: none;
    }

    .search-form .form-group input.form-control::-moz-placeholder {
        /* Firefox 19+ */
        display: none;
    }

    .search-form .form-group input.form-control:-ms-input-placeholder {
        display: none;
    }

    .search-form .form-group:hover,
    .search-form .form-group.hover {
        width: 100%;
        border-radius: 4px 25px 25px 4px;
    }

    .search-form .form-group span.form-control-feedback {
        position: absolute;
        top: -1px;
        right: -2px;
        z-index: 2;
        display: block;
        width: 34px;
        height: 34px;
        line-height: 34px;
        text-align: center;
        color: #3596e0;
        left: initial;
        font-size: 14px;
    }
</style>

Next, add a script tag in your template2.html file and add this code:

接下来,在您的template2.html文件中添加一个脚本标记,并添加以下代码:

template2.html
template2.html
// instantiate a new Elasticsearch client like you did on the client
var client = new elasticsearch.Client({
    hosts: ['http://127.0.0.1:9200']
});
// create a new Vue instance
var app = new Vue({
    el: '#app',
    // declare the data for the component (An array that houses the results and a query that holds the current search string)
    data: {
        results: [],
        query: ''
    },
    // declare methods in this Vue component. here only one method which performs the search is defined
    methods: {
        // function that calls the elastic search. here the query object is set just as that of the server.
        //Here the query string is passed directly from Vue
        search: function() {
            var body = {
                    size: 200,
                    from: 0,
                    query: {
                        match: {
                            name: this.query
                        }
                    }
                }
                // search the Elasticsearch passing in the index, query object and type
            client.search({ index: 'scotch.io-tutorial', body: body, type: 'cities_list' })
                .then(results => {
                    console.log(`found ${results.hits.total} items in ${results.took}ms`);
                    // set the results to the result array we have 
                    this.results = results.hits.hits;
                })
                .catch(err => {
                    console.log(err)

                });


        }
    },
    // declare Vue watchers
    watch: {
        // watch for change in the query string and recall the search method
        query: function() {
            this.search();
        }
    }

})

The HTML and JavaScript snippet above is similar to the one in the previous step, with the main differences being as follows:

上面HTML和JavaScript代码段与上一步中的代码段相似,主要区别如下:

  • You did not require Axios, you required elasticsearch.js instead.

    您不需要Axios ,而是需要elasticsearch.js

  • At the top of the script tag, you initiated the Elasticsearch client as it was done on the server-side.

    在脚本标签的顶部,您像在服务器端一样启动了Elasticsearch客户端。
  • The search method does not perform an HTTP request, but rather searches the Elasticsearch engine as done in the search route on the server side.

    搜索方法不执行HTTP请求,而是像在服务器端的搜索路由中一样搜索Elasticsearch引擎。

If you browse to http://localhost:3001/v2, It should work as shown:

Client side searching from the search app

如果浏览到http://localhost:3001/v2 ,则应如下所示工作:

结论 (Conclusion)

In this tutorial, you used Elasticsearch to index data. You have also implemented a real-time search using the client library for Elasticsearch.

在本教程中,您使用Elasticsearch索引了数据。 您还使用Elasticsearch的客户端库实现了实时搜索。

翻译自: https://www.digitalocean.com/community/tutorials/how-to-build-a-real-time-search-engine-with-node-vue-and-elasticsearch

node vue 实时推送

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值