更新时间:2024-08-08 GMT+08:00
分享

对接CSS提供云搜索服务

背景信息

云搜索服务(Cloud Search Service,简称CSS),为您提供托管的分布式搜索引擎服务,完全兼容开源Elasticsearch搜索引擎,支持结构化、非结构化文本的多条件检索、统计、报表。云搜索服务的使用流程和数据库类似,更多介绍请参见云搜索服务

在AstroZero中,通过应用与CSS (Cloud Search Service)对接,实现云搜索服务功能。

场景描述

使用云搜索服务创建索引。

前提条件

参照如下操作,获取CSS提供服务的URL地址。

  1. 登录云搜索服务控制台。
  2. 在左侧导航栏中,选择“集群管理”。
  3. 在集群管理列表中,获取“内网访问地址”的值。

新建CSS连接器

  1. 参考创建连接器入口中操作,进入创建连接器页面。
  2. 在左侧列表中,选择“数据库 > 云搜索”,单击“+”。

    图1 添加云搜索连接器

  3. 设置CSS对接参数,单击“保存”。

    图2 设置CSS对接参数
    • 名称:连接器的名称。
    • 地址:CSS提供服务的URL地址,配置为前提条件中获取的值。
    • 版本:ElasticSearch的大版本号,目前支持版本6和7。
    • 安全模式:在安全模式访问集群时,将进行通讯加密及安全认证。安全模式下,若地址未指明协议,将默认使用https。
    • 使用证书:仅在使用https协议,且无法通过证书校验时,才需要使用自定义的证书。

      该证书将用于构建客户端,以验证服务端的真实性,当前支持x509格式的证书。

    • 打包当前配置:默认为选中,对信息敏感的场景,建议不勾选。

      选中该选项后,应用打包时会将当前配置的连接器信息一并打出。例如,如果应用包发布到运行环境,当前配置默认会被同步到运行环境中。

在脚本中调用连接器

在脚本中,调用连接器实现与CSS的对接。

  1. 参考开发一个简单脚本实例中操作,创建一个空白脚本。

    图3 新建一个空白脚本

  2. 在脚本编辑器中,输入如下代码。

    //导入该脚本所依赖的标准库文件。es是系统预置的标准库。
    import * as es from 'es'
    
    /
       ES模块部分脚本接口调用示例
    */
    
    let indexName1 = "indexName1"
    let indexName2 = "indexName2"
    let aliasName = "alias"
    
    let client = es.newClient('CSS1') //创建客户端需要输入连接器实例名称,这里举例为“CSS1”
    
    //1. 准备,如果已经存在索引,先进行删除(删除索引同时会删除索引内文档)
    let exist = client.checkIndexExist(indexName1)
    if (exist) { client.dropIndex(indexName1) }
    exist = client.checkIndexExist(indexName2)
    if (exist) { client.dropIndex(indexName2) }
    client.createIndex(indexName1) //创建一个没有映射的索引(根据插入的文档动态生成映射)
    
    //2. 插入或更新文档,如果已存在同id文档则更新,不存在则插入
    let doc = {
        "_id": "1001",     //自定义的文档ID,若不指定_id,则自动生成唯一随机的文档ID
        "foo": "apple",
        "bar": 30,
    }
    let docID = client.indexDoc(indexName1, doc) //返回index的文档id
    console.log("docID: ", docID) //此处docID为1001
    
    //3. 批量插入或更新文档
    let docs = [    //再定义两个文档
        {
            "_id": "1002",
            "foo": "banana",
            "bar": 40,
        },
        {
            "_id": "1003",
            "foo": "orange",
            "bar": 50,
            "baz": true,
        }
    ]
    client.bulkIndexDocs(indexName1, docs)
    
    //4. 局部更新文档
    client.updateDocByDocID(indexName1, "1001", {
        bar: 35,     //局部更新,只将bar字段改为35
        qux: "none",    //局部添加新字段和值
    })
    
    //5. 增删改之后可以显式调用refresh进行刷新,否则需等待约1秒之后,才可被搜
    client.refresh(indexName1)
    
    //6. 查记录数
    let count = client.countDocs(indexName1)
    console.log("count: ", count) //应打印3
    
    //7. 按条件查
    let condition = { 
        query: {
            range: {
                bar: { gte: 40 }
            }
        }
    }
    let searchRes = client.search(condition, indexName1)  //查询bar字段大于40的文档
    console.log("searchRes: ", searchRes)   //此处会打印出两个匹配的文档
    
    //8. 按条件更新
    let script = 'ctx._source.bar = 70' 
    let query = {
        match: {
            foo: "apple",
        }
    }
    let updatedCount = client.updateByQuery(indexName1, query, script) //批量更新,把foo为apple的文档的bar都变为70
    console.log("updatedCount: ", updatedCount) //打印出改动的文档数量,此处打印1
    client.refresh(indexName1)
    
    //9. 仅查询id列表
    let idList = client.searchIDList(indexName1, {
        query: {
            match_all: {}   //全部查询
        },
        size: 5  //指定最多搜出5个结果
    })
    console.log("idList: ", idList) //会打印 ["1001","1002","1003"]
    
    //10. 轻量查询(相比于search,query不需要写json条件,只需要简单字符串查询即可)
    let queryRes = client.query("foo:apple", false, indexName1) //查询foo字段为apple的文档, 第二个参数false表示只查前十个文档,为true则为全查
    console.log("queryRes1: ", queryRes) //会有1个查询结果
    queryRes = client.query("foo:apple OR banana", false, indexName1) //除了foo字段为apple的文档,再加上全文查询banana的结果
    console.log("queryRes2: ", queryRes) //会有2个查询结果
    
    //11. 创建第二个索引,自定义映射
    let mp = {
        dynamic: "strict",
        properties: {
            name: { type: "text"    },
            age: {  type: "integer" }
        }
    }
    client.createIndexWithMapping(indexName2, mp)
    
    //12. 获得索引的映射
    let mpRes = client.getMapping(indexName2)
    console.log("mapping: ", mpRes)    //打印出映射
    
    //13. 绑定别名
    client.attachAlias(indexName1, aliasName)
    
    //14. 对别名操作和对索引操作一致
    client.deleteDocByDocID(aliasName, "1001")
    client.refresh(aliasName)
    count = client.countDocs(aliasName)
    console.log("countAfterDelete: ", count) //这里会打印2
    
    //15. 得到别名关联的索引
    let attached = client.getAttachedIndexes(aliasName)
    console.log(attached)   //这里会打印出indexName1
    
    //16. 得到索引管理的别名
    let ali = client.getAlias(indexName1)
    console.log(ali)    //打印出alias的名字
    
    //17. 同时绑定新索引,解绑旧索引
    client.attachAndDetachAlias(indexName2, indexName1, aliasName)
    attached = client.getAttachedIndexes(aliasName)
    console.log(attached)   //打印出indexName2
    
    //18. 获取当前所有索引的基本信息(对应的别名、文档数)
    let catRes = client.cat()
    console.log("catRes: ", catRes)

    其中,es.newClient('NS__CSS1')中“NS__CSS1”为连接器的名称。

  3. 单击脚本编辑器页面上方的,保存脚本。
  4. 保存成功后,单击,运行脚本。
  5. 不用设置输入参数,直接单击测试窗口右上角的
  6. 在日志页签,可查看到创建了索引。

    0826 10:20:14.685|debug|vm[86]>>> AstroZero 1.2.8 - Production on 2019-08-23 14:44:06 2ce004a222b087e3ac55c70d4e2482d7338d81aa debug (<unknown>.ts:0)
    0826 10:20:14.685|debug|vm[86]>>> script: Test_CSS1 1.0.1  (<unknown>.ts:0)
    0826 10:20:14.685|debug|vm[86]>>> locale: zh_CN (<unknown>.ts:0)
    0826 10:20:14.685|debug|vm[86]>>> timezone: (GMT+00:00) Greenwich Mean Time (GMT) (<unknown>.ts:0)
    0826 10:20:14.766|debug|vm[86]>>> docID:  1001 (Test_CSS1.ts:28)
    0826 10:20:14.812|debug|vm[86]>>> count:  3 (Test_CSS1.ts:57)
    0826 10:20:14.815|debug|vm[86]>>> searchRes:  {
        "aggregations": {},
        "hits": [
            {
                "_id": "1002",
                "_index": "indexname1",
                "_score": 1,
                "_source": {
                    "bar": 40,
                    "foo": "banana"
                },
                "_type": "_doc"
            },
            {
                "_id": "1003",
                "_index": "indexname1",
                "_score": 1,
                "_source": {
                    "bar": 50,
                    "baz": true,
                    "foo": "orange"
                },
                "_type": "_doc"
            }
        ],
        "max_score": 1,
        "total": {
            "relation": "eq",
            "value": 2
        }
    } (Test_CSS1.ts:68)
    0826 10:20:14.82|debug|vm[86]>>> updatedCount:  1 (Test_CSS1.ts:78)
    0826 10:20:14.831|debug|vm[86]>>> idList:  [
        "1002",
        "1003",
        "1001"
    ] (Test_CSS1.ts:88)
    0826 10:20:14.833|debug|vm[86]>>> queryRes1:  {
        "_id": "1001",
        "_index": "indexname1",
        "bar": 70,
        "foo": "apple",
        "qux": "none"
    } (Test_CSS1.ts:92)
    0826 10:20:14.835|debug|vm[86]>>> queryRes2:  {
        "_id": "1002",
        "_index": "indexname1",
        "bar": 40,
        "foo": "banana"
    },
    {
        "_id": "1001",
        "_index": "indexname1",
        "bar": 70,
        "foo": "apple",
        "qux": "none"
    } (Test_CSS1.ts:94)
    0826 10:20:14.879|debug|vm[86]>>> mapping:  {
        "age": {
            "type": "integer"
        },
        "name": {
            "type": "text"
        }
    } (Test_CSS1.ts:108)
    0826 10:20:14.898|debug|vm[86]>>> countAfterDelete:  2 (Test_CSS1.ts:117)
    0826 10:20:14.899|debug|vm[86]>>> indexname1 (Test_CSS1.ts:121)
    0826 10:20:14.899|debug|vm[86]>>> alias (Test_CSS1.ts:125)
    0826 10:20:14.908|debug|vm[86]>>> indexname2 (Test_CSS1.ts:130)
    0826 10:20:14.912|debug|vm[86]>>> catRes:  [
        {
            "indexName": "indexname1",
            "aliases": null,
            "docCount": 2
        },
        {
            "indexName": "indexname2",
            "aliases": [
                "alias"
            ],
            "docCount": 0
        }
    ] (Test_CSS1.ts:134)

  7. 单击脚本编辑器页面上方的,启用脚本。
  8. 在连接器详情页面的“相关脚本”中,单击“管理脚本”,将上一步启用的脚本拖入“已选择”区域,单击“保存”。

    图4 单击“管理脚本”
    图5 选择脚本

  9. 在连接器详情页面的“相关脚本”中,单击脚本操作列的

    在“索引”区域,可查看到脚本的执行结果,即添加了“indexname1”和“indexname2”索引。

    图6 查看索引添加结果

相关文档