本节只是尝试使用nodejs中的elasticsearch模块实现elasticsearch在node环境下的基本增删改查。
具体方法详情可查看官网JavaScript API:https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html
var elasticsearch=require('elasticsearch');
var client=new elasticsearch.Client({
host:"localhost:9200",
//将日志信息显示在控制台,默认level:"console"
log:"trace",
//将日志信息写入文件中
// log:{
// type:'file',
// level:"trace",
// path:"url"
// }
//设置不同等级输出到不同的地方
// log:[
// {
// type:'console',
// level:"error",
// },
// {
// type:"file",
// level:"trace",
// path:"url"
// }
// ]
});
//一次性执行多个命令
async function bulk(){
let resp;
try{
resp=await client.bulk({
body: [
// action description
{ index: { _index: 'myindex', _type: 'mytype', _id: 1 } },
// the document to index
{ title: 'foo' },
// action description
{ update: { _index: 'myindex', _type: 'mytype', _id: 2 } },
// the document to update
{ doc: { title: 'foo' } },
// action description
{ delete: { _index: 'myindex', _type: 'mytype', _id: 3 } },
// no document needed for this delete
]
});
}catch(e){
resp=null;
}
return resp;
}
//获取符合条件的数量
async function count(index_name){
let resp ;
try{
resp= await client.count({
index: index_name,
// body: {
// query: {
// filtered: {
// filter: {
// terms: {
// title: ['foo']
// }
// }
// }
// }
// }
});
}catch(e){
resp=null;
}
return resp;
}
async function create(){//index,type相同时id重复时插入失败
let resp;
try{
resp=await client.create({
index: 'myindex',
type: 'mytype',
id: '2',
body: {
title: 'Test 1',
tags: ['y', 'z'],
published: true,
published_at: '2013-01-01',
counter: 1
}
});
}catch(e){
resp=null;
}
return resp;
}
async function deleteById(index,type,id){//删除指定的文档
let resp;
try{
resp=await client.delete({
index: index,
type: type,
id: id
});
}catch(e){
resp=null;
}
return resp;
}
async function deleteByQuery(){
let resp;
try{
resp=await client.deleteByQuery({
index: 'myindex',
body: {
query: {
term: { published: true }
}
}
});
}catch(e){
resp=null;
}
return resp;
}
//判断某索引是否存在
async function exists(){
let resp;
try{
resp=await client.exists({
index: 'mydatabase',
type: 'mytable',
id: 1543237871246
});
}catch(e){
resp=null;
}
return resp;
}
//查询某索引的详细信息介绍
async function explain(){
let resp;
try{
resp = await client.explain({
index: 'mydatabase',
type: 'mytable',
id: 1543237871246,
body: {
query: {
match: { published: true }
}
}
});
}catch(e){
resp=null;
}
return resp;
}
//获取查询文档的信息
async function get(){
let resp;
try{
resp = await client.get({
index: 'mydatabase',
type: 'mytable',
id:1543237871246
});
}catch(e){
resp=null;
}
return resp;
}
//根据索引index和类型type和id获取对象的源==相当于get()方法返回的对象中的_source字段
async function getSource(){
let resp;
try{
resp=await client.getSource({
index:"mydatabase",
type:"mytable",
id:1543237871246
});
}catch(e){
resp=null;
}
return resp;
}
//添加或者更新文档
/**
* 将类型化JSON文档存储在索引中,
* 使其可搜索。当id参数未设置时,
* 将自动生成唯一的id。
* 当您指定一个id时,要么创建一个新文档,
* 要么更新一个现有文档
*/
async function index(){
let resp;
try{
resp=await client.index({
index:"mydatabase",
type:"mytable",
id:1543237871252,
body:{
title:"hasprice",
tags:["index1","index2"],
published:true,
price:30
}
});
}catch(e){
resp=null;
}
return resp;
}
/**
* 从当前集群获取基本信息
*/
async function info(){
let resp;
try{
resp=await client.info();
}catch(e){
resp=null;
}
return resp;
}
/**
* 根据索引、类型(可选)和id获取多个文档。
* mget所需的主体可以采用两种形式:
* 文档位置数组,或文档id数组。
*/
async function mget(){
let resp;
try{
resp=await client.mget({
body:{
docs:[//位置数组
{_index:"mydatabase",_type:"mytable",_id:1543237871246},
{_index:"mydatabase",_type:"mytable",_id:1543237871247}
]
//ids:[1,2,3]//文档id数组
}
})
}catch(e){
resp=null;
}
return resp;
}
/**
* 在同一个请求中执行多个搜索请求
*/
async function msearch(){
let resp;
try{
resp=await client.msearch({
body:[
//匹配所有索引和类型上的所有查询
/*{},
{
query:{
match_all:{}
}
}*/
//在index和type的查询条件下查询
/*{index:'mydatabase',type:"mytable"},
{query:{query_string:{query:'test 1'}}}*/
//resp.responses[0].hits.hits[0]._source获取其内容
]
});
}catch(e){
resp=null;
}
return resp;
}
async function search(){//resp.hits.hits[0]._source
let resp;
try{
resp=await client.search({
index:"mydatabase",
//q:"title:test2"//使用简单的查询字符串查询进行搜索
body:{
"query":{
"bool":{
"must":[
{
"term":{
"title":"hasprice"
}
}
]
}
}
},
"from":0,
"size":10,
"sort":["price:desc"]//按price降序排序
});
}catch(e){
resp=null;
}
return resp;
}
async function searchTemplate(){
let resp;
try{
resp=await client.searchTemplate({
index:"mydatabase",
body:{
"source":{
"query":{
"match":{
"{{name}}":"{{value}}"
}
},
size:5//显示查询的数组的长度
},
params:{
"name":"tag",
"value":"1"
}
}
})
}catch(e){
resp=null;
}
return resp
}
/**
* 更新文档的部分内容。所需的body参数可以包含以下两种情况之一:
* 将与现有文档合并的部分文档。
* 更新文档内容的脚本
*/
async function update(){
let resp;
let params={tags:'tag1'}
try{
resp=await client.update({
index:'mydatabase',
type:"mytable",
id:1543237871247,
body:{
//将部分文档放在“doc”属性下
// doc:{
// title:"updated"
// }
//使用脚本向文档标记属性添加标记,1543237871248 存在,会在tag的基础上变化
//script:`ctx._source.tag =1`,
//script:`ctx._source.tag += ctx._source.tag`,
//script:`ctx._source.tag += "${params.tags}"`
//当文档不存在时,将文档计数器增加1或初始化它 1543237871249为不存在的,当执行此语句时会初始化tag=1
// script:'ctx._source.tag+=1',
// upsert:{
// tag:1
// }
//如果你想让你的脚本运行,不管文档是否存在。脚本处理初始化文档,而不是upsert元素——然后将scripted_upsert设置为true
/*"scripted_upsert":true,
"script":{
"source":"ctx._source.tag=params.tag",
"params":{
"tag":"haha"//此时如果文档不存在,会初始化为haha而不是1
}
},
"upsert":{
tag:"1"
}*/
//可以读取参数的写法
// script:{
// "source":"ctx._source.tag+=params.count",
// "lang":"painless",
// "params":{
// "count":4
// }
// }
//移除tag属性
// script:{
// "source":"ctx._source.remove('tag')"
// }
//可用doc来取代upsert功能初始化tag的值
/*"doc":{
"tag":"doc"
},
"doc_as_upsert":true*/
//根据query修改符合指定条件的修改
/*"script":{
"source":"ctx._source.tag=1",
"lang":"painless"
},
"query":{
"term":{
"title":"test2"
}
}*/
//source 也可以用if语句
"script":{
"source":"if(ctx._source.tag==-1){ctx._source.tag-=1}else{ctx._source.tag+=1}",
"lang":"painless"
}
}
})
}catch(e){
resp=null;
}
return resp;
}
(async function(){
let resp=await search();
console.log(resp.hits.hits)
})();
上文一些方法只是初步的功能测试,如果想达到实际使用的要求,例如搜索功能,处理人类语言(分词,分析)等可以参考官网的权威指南和api:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html。
后续会更新elasticsearch在实际应用中的使用。