热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

運用Node,Vue和ElasticSearch構建及時搜索引擎

(譯者注:相干閱讀:node.js,vue.js,Elasticsearch)引見Elasticsearch是一個分佈式的RESTful搜刮和剖析引擎,能夠處置懲罰越來越多的用例。

(譯者注:相干閱讀:node.js,vue.js,Elasticsearch)

引見

Elasticsearch是一個分佈式的RESTful搜刮和剖析引擎,能夠處置懲罰越來越多的用例。 Elasticsearch豎立在Apache Lucene之上,它是一個高性能的文本搜刮引擎庫。

目次

在本日的課程中,您將進修怎樣運用Node.js,Elasticsearch和Vue.js構建及時搜刮引擎。因而,須要對本教程舉行基礎的Vue.js和Node.js(Express)明白。

入門

讓我們最先為本課設置環境。由於您將運用Node.js,因而最簡樸的入門要領是豎立一個新文件夾並運轉npm init。豎立一個名為elastic-node的新文件夾,將目次變動成新文件夾,然後運轉npm init:

//豎立一個名為elastic-node的新目次
mkdir elastic-node
//將目次變動成豎立的新文件夾
cd elastic-node
//運轉npm init來豎立一個package.json文件
npm init

上述敕令將指導您完成豎立package.json文件的歷程,該文件是運轉任何Node.js庫所必需的。接下來,您須要裝置及時搜刮引擎所需的庫。所需的庫是:

  • Express: 這個庫將運轉我們的效勞器
  • Body-parser: 該庫與Express一同運用來剖析正文要求。
  • Elasticsearch: 這是Elasticsearch的官方Node.js庫,它是及時搜刮的引擎。

要裝置這些庫,實行:

npm install express body-parser elasticsearch

如今,您的環境的第一部份已豎立。然則,您的設置中缺乏Elasticsearch。您將須要裝置Elasticsearch。有差別的要領來裝置Elasticsearch。假如您運用Debian Linux操縱體系,則能夠下載.deb文件並運用dpkg舉行裝置。

//下載deb包
curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.6.4.deb
//運用dpkg裝置deb包
sudo dpkg -i elasticsearch-5.6.4.deb

關於其他發行版/操縱體系,您能夠在 這裏找到關於怎樣裝置Elasticsearch的指南。

Elasticsearch裝置后不會自動啟動。 Elasticsearch能夠運用效勞敕令啟動和住手:

// 啟動Elasticsearch效勞
sudo -i service elasticsearch start
// 住手Elasticsearch效勞
sudo -i service elasticsearch stop

要將Elasticsearch設置為在體系啟動時自動啟動,請運轉:

// 從新加載systemctl保衛歷程
sudo /bin/systemctl daemon-reload
// enable elastic search so it can be called as a service
sudo /bin/systemctl enable elasticsearch.service

運轉上面的敕令后,您能夠運轉以下敕令來啟動和住手Elasticsearch:

// 啟動Elasticsearch效勞
sudo systemctl start elasticsearch.service
// 住手Elasticsearch效勞
sudo systemctl stop elasticsearch.service

搜檢Elasticsearch的狀況:

// Elasticsearch的狀況
sudo service elasticsearch status

注重:
Google Chrome Elastic工具箱能夠協助您疾速檢察Elasticsearch的索引和文檔。

在Elasticsearch中索引數據

在根文件夾中豎立一個data.js文件並增加:

//data.js
//require the Elasticsearch librray
const elasticsearch = require('elasticsearch');
// 實例化一個Elasticsearch客戶端
const client = new elasticsearch.Client({
hosts: [ 'http://localhost:9200']
});
// ping客戶端以確保Elasticsearch已啟動
client.ping({
requestTimeout: 30000,
}, function(error) {
// 此時,eastic搜刮已封閉,請搜檢您的Elasticsearch效勞
if (error) {
console.error('Elasticsearch cluster is down!');
} else {
console.log('Everything is ok');
}
});

讓我來解釋一下你在上面的代碼塊中所做的事變:起首,你須要Elasticsearch庫,並豎立一個新的Elasticsearch客戶端傳入一個主機的數組。假如您注重到,主機是http:// localhost:9200。這是由於默許情況下,Elasticsearch在端口9200上監聽。接下來,您ping Elasticsearch客戶端以確保效勞器已啟動。假如你運轉節點data.js,你應當獲得一個音訊說一切正常。

相識索引

與一般數據庫差別,Elasticsearch索引是存儲相干文檔的處所。比方,您將豎立一個名為scotch.io-tutorial的索引來存儲範例為cities_list的數據。這就是Elasticsearch所做的事情:

// data.js
// 豎立一個名為scotch.io-tutorial的新索引。假如索引已被豎立,這個函數會平安地失利
client.indices.create({
index: 'scotch.io-tutorial'
}, function(error, response, status) {
if (error) {
console.log(error);
} else {
console.log("created a new index", response);
}
});

在之前編寫的ping功用以後增加這段代碼。如今再次運轉node data.js,你應當獲得兩條音訊:

  • Everything is okay(一切正常)
  • Created a new index (with the response from Elasticsearch)(豎立了一個新的索引(來自Elasticsearch的相應) )

將文檔增加到索引

Elasticsearch API使文檔能夠輕鬆增加到已豎立的索引中。以下:

// 將數據增加到已豎立的索引
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);
});

上面的代碼塊是解釋性的。正文指的是您要增加到scotch.io-tutorial索引的文檔,而範例更多的是一個種別。然則,請注重,假如id鍵被省略,Elasticsearch將自動天生一個。

然則,在本課中,您的文檔將成為世界上一切都市的列表。假如您要逐一增加每一個都市,那末須要幾天時刻(假如不是幾周)才完整索引一切都市。榮幸的是,Elasticsearch有一個用於處置懲罰批量數據的批量函數。

起首,抓取包含世界上一切都市的JSON文件,並保留到您的根文件夾中作為cities.json

如今是時刻運用批量API來導入我們大批數據了:

//data.js
// require the array of cities that was downloaded
const cities = require('./cities.json');
// 聲明一個名為bulk的空數組
var bulk = [];
// 輪迴遍歷每一個都市,並在每一個輪迴中豎立並將兩個對象推入數組中
// 第一個對象發送索引和範例,保留數據
// 第二個對象是你想索引的數據
cities.forEach(city =>{
bulk.push({index:{
_index:"scotch.io-tutorial",
_type:"cities_list",
}
})
bulk.push(city)
})
// 對通報的數據實行批量索引
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);
}
});

在這裏,您已閱讀了JSON文件中的一切都市,而且在每一個輪迴中,您都邑追加一個包含要索引的文檔的索引和範例的對象。請注重,在輪迴中有兩個推入數組?這是由於批量API須要起首包含索引定義的對象,然後是要索引的文檔。欲相識更多信息,你能夠在這裏檢察。

接下來,您將通報給新的批量數組的client.bulk函數作為正文挪用。這會將一切數據用scotch.io-tutorial的索引和範例cities_list索引到Elasticsearch中。

引入Express

您的Elasticsearch實例已啟動並正在運轉,您能夠運用Node.js銜接它。如今是時刻運用Express來為目的頁面供應效勞,並運用迄今為止運轉的設置。

豎立一個名為index.js的文件並增加:

//index.js
// 須要Elasticsearch librray
const elasticsearch = require('elasticsearch');
// 實例化一個elasticsearch客戶端
const client = new elasticsearch.Client({
hosts: [ 'http://localhost:9200']
});
//require Express
const express = require( 'express' );
// 實例化一個表達式的實例並將其保留在一個名為app的常量中
const app = express();
// 引入body-parser庫。將用於剖析主體要求
const bodyParser = require('body-parser')
//require the path library
const path = require( 'path' );
// ping客戶端以確保Elasticsearch已啟動
client.ping({
requestTimeout: 30000,
}, function(error) {
// 此時,eastic搜刮已封閉,請搜檢您的Elasticsearch效勞
if (error) {
console.error('elasticsearch cluster is down!');
} else {
console.log('Everything is ok');
}
});
// 運用bodyparser作為中間件
app.use(bodyParser.json())
// 設置應用程序偵聽的端口
app.set( 'port', process.env.PORT || 3001 );
// 設置途徑來供應靜態文件
app.use( express.static( path.join( __dirname, 'public' )));
// 啟用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();
});
// 定義了基礎路線並返回一個名為tempate.html的HTML文件
app.get('/', function(req, res){
res.sendFile('template.html', {
root: path.join( __dirname, 'views' )
});
})
// 定義應當返回彈性搜刮效果的/ search途徑
app.get('/search', function (req, res){
// 聲明查詢對象以搜刮彈性搜刮,並從找到的第一個效果中僅返回200個效果。
// 還婚配个中稱號與發送的查詢字符串類似的任何數據
let body = {
size: 200,
from: 0,
query: {
match: {
name: req.query['q']
}
}
}
// 在索引中實行現實的搜刮通報,搜刮查詢和範例
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([]);
});
})
// 監聽一個指定的端口
app .listen( app.get( 'port' ), function(){
console.log( 'Express server listening on port ' + app.get( 'port' ));
} );

看看上面的代碼,注重:

  • 須要Express,body-parser和途徑庫。
  • 將一個新的Express實例設置為常量,命名為app。
  • 設置應用程序以運用bodyParser中間件。
  • 將應用程序的靜態文件放在名為public的文件夾(我還沒有豎立此文件夾)。
  • 定義了一個將CORS頭增加到應用程序的中間件。
  • 定義一個GET路由在根目次文件夾里,而且在此路由中,我返回了一個名為template.html的文件,該文件位於views文件夾中(我還還沒有豎立此文件夾和文件template.html)
  • 為應用程序的/ 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.

相識搜刮API相應

假如您要註銷搜刮API的相應,則會包含大批信息。

{ 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] ] } }

相應中包含一個用於查找效果的毫秒數的爭取屬性timed_out,假如在最大許可時刻內未找到效果,則返回true; _shards用於獵取有關差別節點狀況的信息(假如布置為節點集群)以及包含搜刮效果的婚配。

在hits屬性中,我們有一個對象具有以下屬性:

總數顯現婚配項目的總數。

max_score是找到的項目的最高分數。

擲中包含找到的項目的數組。

以上是搜刮路由的前提,您返回了response.hits.hits,个中包含找到的文檔。

豎立HTML模板

起首,在上面的部份中援用的名為views和public的根文件夾中豎立兩個新文件夾。接下來,在views文件夾中豎立一個名為template.html的文件並粘貼:








Search Cities around the world




















{{ result._source.name }}, {{ result._source.country }}



lat:{{ result._source.lat }}, long: {{ result._source.lng }}.







在上面的代碼片斷中,有兩個重要部份:

  • HTML代碼:在本節中,您起首須要三個差別的庫,分別是1.)Bootstrap CSS,用於設置頁面款式。 2.)Axios js,用於向我們的效勞器發送HTTP要求,以及3)Vue.js,一個您將用於我們的視圖的簡約框架。
  • CSS代碼:在這裏,您將懸停在搜刮圖標上的款式應用於隱蔽和顯現搜刮輸入。

接下來,為您指定其v模子舉行查詢的搜刮框有一個輸入(這將由Vue.js運用)。在此以後,您輪迴遍歷一切效果(此輪迴和效果變量將由Vue.js供應)。請注重,在此輪迴時,您必需接見數據的__source屬性。基於彈性搜刮返回的相應,這看起來很熟悉。

運轉node index.js敕令,閱讀到http:// localhost:3001 /,接下來,在你的template.html文件中增加一個劇本標籤,增加:

// template.html
// 豎立一個新的Vue實例
var app = new Vue({
el: '#app',
// 聲明組件的數據(包容效果的數組以及包含當前搜刮字符串的查詢) search string)
data: {
results: [],
query: ''
},
// 在這個Vue組件中聲明要領。這裏只定義了一種實行搜刮的要領
methods: {
// 運用當前搜刮查詢向效勞器發出axios要求
search: function() {
axios.get("http://127.0.0.1:3001/search?q=" + this.query)
.then(respOnse=> {
this.results = response.data;
})
}
},
// declare Vue watchers
watch: {
// 注重查詢字符串中的變動並挪用搜刮要領
query: function() {
this.search();
}
}
})

Vue.js代碼:在本節中,您聲清楚明了一個Vue的新實例,將其掛載到具有應用程序ID的元素上。您聲清楚明了數據屬性,个中包含1)查詢您已附加到搜刮輸入,和2)效果,這是一切找到的效果的數組。

在要領設置中,只要一個稱為搜刮的函數,它會觸發搜刮途徑的GET要求,以通報搜刮框中的當前輸入。然後會返回一個相應,然後在HTML代碼塊中輪迴。

末了,您運用Vue.js中的所謂視察者,在任何時刻都能夠看管數據以檢察變動。在這裏,您正在視察查詢數據中的變動,而且一旦它發作變動,就會觸發搜刮要領。

從客戶端搜刮

每次搜刮發作時,假如我不想將要求發送到效勞器,該怎麼辦?我能夠直接從客戶端搜刮Elasticsearch引擎嗎?是。

只管上述要領有用,但有些開發人員能夠並不習慣於每次搜刮前提都運用他們的效勞器,有些則以為從效勞器端舉行搜刮更平安。

然則,能夠從客戶端舉行搜刮。 Elasticsearch供應了能夠舉行搜刮的閱讀器版本。讓我經由過程一個疾速示例。

起首,將一條新路線增加到Express文件並從新啟動效勞器:

//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' )
});
})

在上面的代碼塊中,您為/ v2豎立了一個新的URL路由,而且您在此路由中所做的一切操縱都將返回一個名為template2.html的靜態HTML文件,該文件將很快豎立。

接下來,您須要在這裏下載Elasticsearch的客戶端庫。下載后,將elasticsearch.min.js提取並複製到應用程序根目次中的公用文件夾。

注重:相識您是不是嘗試從客戶端銜接Elasticsearch引擎異常重要,您能夠會碰到CORS題目。為了處置懲罰這個題目,找到你的Elasticsearch設置文件(關於Debian / Ubuntu,能夠在/etc/elasticsearch/elasticsearch.yml找到它)。關於其他操縱體系,找到它位於的位置,並將以下內容增加到底部文件:

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

完成以後,從新啟動Elasticsearch實例

// 從新啟動Elasticsearch效勞
sudo service elasticsearch restart

接下來,在視圖文件夾中豎立一個名為template2.html的文件並增加:








Search Cities around the world




















{{ result._source.name }}, {{ result._source.country }}



lat:{{ result._source.lat }}, long: {{ result._source.lng }}.








接下來,在您的template2.html文件中增加一個劇本標記並增加:

//template2.html
// 像你在客戶端上那樣實例化一個新的Elasticsearch客戶端
var client = new elasticsearch.Client({
hosts: ['http://127.0.0.1:9200']
});
// 豎立一個新的Vue實例
var app = new Vue({
el: '#app',
// 聲明組件的數據(包容效果的數組以及包含當前搜刮字符串的查詢)
data: {
results: [],
query: ''
},
// 在這個Vue組件中聲明要領。這裏只定義了一種實行搜刮的要領
methods: {
// 函數挪用彈性搜刮。這裏查詢對象與效勞器的設置一樣。
// 這裏查詢字符串直接從Vue通報
search: function() {
var body = {
size: 200,
from: 0,
query: {
match: {
name: this.query
}
}
}
// 搜刮傳入索引的Elasticsearch,查詢對象和範例
client.search({ index: 'scotch.io-tutorial', body: body, type: 'cities_list' })
.then(results => {
console.log(found ${results.hits.total} items in ${results.took}ms);
// 將效果設置為我們具有的效果數組
this.results = results.hits.hits;
})
.catch(err => {
console.log(err)
});
}
},
// declare Vue watchers
watch: {
// 注重查詢字符串中的變動並挪用搜刮要領
query: function() {
this.search();
}
}
})

上面的HTML和Javascript片斷與上面的部份異常類似。唯一的區別是:

  • 您不須要Axios,而是須要elasticsearch.js。
  • 在劇本標記的頂部,您啟動了Elasticsearch客戶端,由於它在效勞器端完成。
  • 搜刮要領不實行HTTP要求,而是像在效勞器端的搜刮途徑中那樣搜刮Elasticsearch引擎。

原文閱讀:https://scotch.io/tutorials/b…


推荐阅读
author-avatar
西安黄河文化补习学校
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有