清除过滤器
文章
Hao Ma · 一月 10, 2021
在本文中,我想谈一谈规范优先的 REST API 开发方式。
传统的代码优先 REST API 开发是这样的:
* 编写代码
* 使其支持 REST
* 形成文档(成为 REST API)
规范优先遵循同样的步骤,不过是反过来的。 我们先制定规范(同时兼做文档),然后根据它生成一个样板 REST 应用,最后编写一些业务逻辑。
这是有好处的,因为:
* 对于想要使用你的 REST API 的外部或前端开发者,你总是有相关且有用的文档
* 使用 OAS (Swagger) 创建的规范可以导入各种工具,从而进行编辑、客户端生成、API 管理、单元测试和自动化,或者许多其他任务的简化
* 改进了 API 架构。 在代码优先的方式中,API 是逐个方法开发的,因此开发者很容易失去对整体 API 架构的跟踪,但在规范优先的方式中,开发者被强制从 API 使用者的角度与 API 进行交互,这通常有助于设计出更简洁的 API 架构
* 更快的开发速度 - 由于所有样板代码都是自动生成的,你无需编写代码,只需开发业务逻辑。
* 更快的反馈循环 - 使用者可以立即查看 API,并且只需修改规范即可轻松提供建议
让我们以规范优先的方式开发 API 吧!
### 计划
1. 使用 swagger 制定规范
* Docker
* 本地
* 在线
2. 将规范加载到 IRIS 中
* API 管理 REST API
* ^REST
* 类
3. 我们的规范会怎样?
4. 实现
5. 进一步开发
6. 注意事项
* 特殊参数
* CORS
7. 将规范加载到 IAM 中
### 制定规范
勿庸置疑,第一步是编写规范。 InterSystems IRIS 支持 Open API 规范 (OAS):
> **OpenAPI 规范** (以前称为 Swagger 规范)是 REST API 的 API 描述格式。 OpenAPI 文件允许描述整个 API,包括:
>
> * 可用端点 (`/users`) 和每个端点上的操作(`GET /users`、`POST /users`)
> * 每次操作的操作参数输入和输出
> * 身份验证方法
> * 联系信息、许可证、使用条款和其他信息。
>
> API 规范可以使用 YAML 或 JSON 编写。 格式易于学习,并且对人和机器都可读。 完整的 OpenAPI 规范可在 GitHub 上找到:[OpenAPI 3.0 规范](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md)
- 来自 Swagger 文档。
我们将使用 Swagger 编写 API。 使用 Swagger 有几种方法:
* [在线](https://editor.swagger.io/)
* Docker:`docker run -d -p 8080:8080 swaggerapi/swagger-editor`
* [本地安装](https://swagger.io/docs/open-source-tools/swagger-editor/)
安装/运行 Swagger 后,你应该在 Web 浏览器中看到以下窗口:
在左侧编辑 API 规范,在右侧可以立即看到渲染的 API 文档/测试工具。
我们将第一个 API 规范加载到其中(使用 [YAML](https://en.wikipedia.org/wiki/YAML))。 这是一个简单的 API,包含一个 GET 请求 - 返回指定范围内的随机数。
Math API 规范
swagger: "2.0"
info:
description: "Math"
version: "1.0.0"
title: "Math REST API"
host: "localhost:52773"
basePath: "/math"
schemes:
- http
paths:
/random/{min}/{max}:
get:
x-ISC_CORS: true
summary: "Get random integer"
description: "Get random integer between min and max"
operationId: "getRandom"
produces:
- "application/json"
parameters:
- name: "min"
in: "path"
description: "Minimal Integer"
required: true
type: "integer"
format: "int32"
- name: "max"
in: "path"
description: "Maximal Integer"
required: true
type: "integer"
format: "int32"
responses:
200:
description: "OK"
以下是其包含的内容。
有关 API 和使用的 OAS 版本的基本信息。
swagger: "2.0"
info:
description: "Math"
version: "1.0.0"
title: "Math REST API"
服务器主机、协议(http、https)和 Web 应用程序名称:
host: "localhost:52773"
basePath: "/math"
schemes:
- http
接下来指定路径(完整的 URL 是 `http://localhost:52773/math/random/:min/:max`)和 HTTP 请求方法(get、post、put、delete):
paths:
/random/{min}/{max}:
get:
之后,指定有关请求的信息:
x-ISC_CORS: true
summary: "Get random integer"
description: "Get random integer between min and max"
operationId: "getRandom"
produces:
- "application/json"
parameters:
- name: "min"
in: "path"
description: "Minimal Integer"
required: true
type: "integer"
format: "int32"
- name: "max"
in: "path"
description: "Maximal Integer"
required: true
type: "integer"
format: "int32"
responses:
200:
description: "OK"
在此部分中,我们定义请求:
* 为 CORS 启用此路径(稍后将详细介绍)
* 提供 _summary_ 和 _description_
* _operationId_ 允许规范内引用,它也是我们的实现类中生成的方法名
* _produces_ - 响应格式(例如文本、xml、json)
* _parameters_ 指定输入参数(在 URL 或正文中),在我们的示例中,我们指定 2 个参数 - 随机数生成器的范围
* _responses_ 列出服务器的可能响应
如你所见,这种格式并不是特别有挑战性,虽然还有很多可用功能。这里是[规范](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md)。
最后,我们将定义导出为 JSON。 转到“文件 → 转换”并另存为 JSON。 规范应如下所示:
Math API 规范
{
"swagger": "2.0",
"info": {
"description": "Math",
"version": "1.0.0",
"title": "Math REST API"
},
"host": "localhost:52773",
"basePath": "/math",
"schemes": [
"http"
],
"paths": {
"/random/{min}/{max}": {
"get": {
"x-ISC_CORS": true,
"summary": "Get random integer",
"description": "Get random integer between min and max",
"operationId": "getRandom",
"produces": [
"application/json"
],
"parameters": [
{
"name": "min",
"in": "path",
"description": "Minimal Integer",
"required": true,
"type": "integer",
"format": "int32"
},
{
"name": "max",
"in": "path",
"description": "Maximal Integer",
"required": true,
"type": "integer",
"format": "int32"
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
}
}
}
### 将规范加载到 IRIS 中
现在我们有了规范,我们可以在 InterSystems IRIS 中为此 REST API 生成样板代码。
要进入此阶段,我们需要三个东西:
* REST 应用程序名称:我们生成的代码的包(假定为 `math)
JSON 格式的 OAS 规范:我们刚刚在上一步中创建
Web 应用程序名称:用于访问我们的 REST API 的基本路径(我们的示例中为 /math`)
有三种方法使用我们的规范来生成代码,它们本质上是相同的,只是提供了多种访问相同功能的方式
1. 调用 `^%REST` 例程(在交互式终端会话中 `Do ^%REST`), [参见文档](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GREST_routine)。
2. 调用 `%REST` 类(`Set sc = ##class(%REST.API).CreateApplication(applicationName, spec)`,非交互式),[参见文档](https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GREST_objectscriptapi)。
3. 使用 API 管理 REST API,[参见文档](https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GREST_apimgmnt)。
我认为文档足以描述所需的步骤,因此选择一个即可。 我再补充两点说明:
* 在第 1 种和第 2 种方法中,可以向动态对象传递文件名或 URL
* 在第 2 种和第 3 种方法中,**必须** 进行一个额外的调用才能创建 Web 应用程序:`set sc = ##class(%SYS.REST).DeployApplication(restApp, webApp, authenticationType)`,所以在我们的示例中为 `set sc = ##class(%SYS.REST).DeployApplication("math", "/math")`,从 `%sySecurity` 包含文件获取 `authenticationType` 参数的值,相关条目为 `$$$Authe*`,因此对于未经身份验证的访问,传递 `$$$AutheUnauthenticated`。 如果省略,该参数默认为密码身份验证。
### 我们的规范会怎样?
如果你已成功创建应用,新的 `math` 包应该包含三个类:
* _Spec_ - 按原样存储规范。
* _Disp_ - 在调用 REST 服务时直接调用。 它封装 REST 处理并调用实现方法。
* _Impl_ - 保存 REST 服务的实际内部实现。 你只应该编辑此类。
[文档](https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GREST_intro#GREST_intro_classes)包含有关这些类的更多信息。
### 实现
最初,我们的实现类 `math.impl` 只包含一个方法,对应于我们的 `/random/{min}/{max}` 操作:
/// Get random integer between min and max
/// The method arguments hold values for:
/// min, Minimal Integer
/// max, Maximal Integer
ClassMethod getRandom(min As %Integer, max As %Integer) As %DynamicObject
{
//(Place business logic here)
//Do ..%SetStatusCode()
//Do ..%SetHeader(,)
//Quit (Place response here) ; response may be a string, stream or dynamic object
}
让我们从简单的实现开始:
ClassMethod getRandom(min As %Integer, max As %Integer) As %DynamicObject
{
quit {"value":($random(max-min)+min)}
}
最后,我们可以通过在浏览器中打开此页面来调用我们的 REST API:`http://localhost:52773/math/random/1/100`
输出应该是:
{
"value": 45
}
此外,在 Swagger 编辑器中按 `Try it out`(试用)按钮并填写请求参数也会发送同样的请求:
恭喜! 我们使用规范优先的方式创建的第一个 REST API 现在已经生效!
### 进一步开发
当然,我们的 API 不是静态的,我们需要添加新路径等等。 在规范优先的开发中,首先要修改规范,然后更新 REST 应用程序(调用与创建应用程序相同),最后编写代码。 请注意,规范更新是安全的:你的代码不会受到影响,即使从规范中删除路径,在实现类中也不会删除方法。
### 注意事项
更多说明!
#### 特殊参数
InterSystems 向 swagger 规范添加了特殊参数,如下所示:
名称
数据类型
默认值
位置
描述
x-ISC_DispatchParent
类名
%CSP.REST
信息
调度类的超类。
x-ISC_CORS
布尔
false
操作
一个标志,指示对此端点/方法组合的 CORS 请求应该获得支持。
x-ISC_RequiredResource
数组
操作
以逗号分隔的已定义资源及其访问模式(资源:模式)的列表,这些资源和模式是访问 REST 服务的此端点所必需的。 示例:["%Development:USE"]
x-ISC_ServiceMethod
字符串
操作
后端调用的用于维护此操作的类方法的名称;默认值为 operationId,通常就很合适。
#### CORS
有三种方法启用 CORS 支持。
1. 在逐条路由的基础上,将 `x-ISC_CORS` 指定为 true。 我们的 Math REST API 中就是这样做的。
2. 在每个 API 的基础上,添加
Parameter HandleCorsRequest = 1;
然后重新编译该类。 规范更新后它也会保留。
3. (推荐)在每个 API 的基础上,实现自定义调度器超类(应该扩展 `%CSP.REST`)并编写 CORS 处理逻辑。 要使用此超类,请将 `x-ISC_DispatchParent` 添加到规范中。
### 将规范加载到 IAM 中
最后,我们将规范添加到 IAM中,以便将其发布给其他开发者。
如果您尚未开始使用 IAM,请参见[此文章](https://community.intersystems.com/post/introducing-intersystems-api-manager)。 它还涵盖了通过 IAM 提供 REST API,所以我在这里不做介绍。 您可能需要修改规范的 `host` 和 `basepath` 参数,使它们指向 IAM,而不是 InterSystems IRIS 实例。
打开 IAM 管理员门户,转到相关工作区的 `Specs`(规范)选项卡。
点击 `Add Spec`(添加规范)按钮并输入新 API 的名称(我们的示例中为 `math`)。 在 IAM 中创建新规范后,点击 `Edit`(编辑)并粘贴规范代码(JSON 或 YAML - IAM 都支持):
不要忘记点击 `Update File`(更新文件)。
现在我们的 API 已发布给开发者。 打开开发者门户,然后点击右上角的 `Documentation`(文档)。 除了三个默认 API,还应该看到我们的新 `Math REST API`:
打开它:
现在,开发者可以看到我们的新 API 的文档,并在同一个地方试用它!
###
### 结论
InterSystems IRIS 简化了 REST API 的开发过程,规范优先的方式使 REST API 生命周期管理更快更简单。 通过这种方式,你可以使用各种工具来完成各种相关任务,例如客户端生成、单元测试、API 管理等等。
### 链接
* [OpenAPI 3.0 规范](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md)
* [创建 REST 服务](https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GREST)
* [从 IAM 开始](https://community.intersystems.com/post/introducing-intersystems-api-manager)
* [IAM 文档](https://docs.intersystems.com/irislatest/csp/docbook/apimgr/index.html)
文章
Louis Lu · 六月 11, 2024
这篇文章介绍了使用由支持 langchain 框架的IRIS来实现问答聊天机器人,其重点介绍了检索增强生成(RAG)。
文章探讨了IRIS中的向量搜索如何在langchain-iris中完成数据的存储、检索和语义搜索,从而实现对用户查询的精确、快速的响应。通过无缝集成以及索引和检索/生成等流程,由IRIS驱动的RAG应用程序使InterSystems开发者能够利用GenAI系统的能力。
为了帮助读者巩固这些概念,文章提供了Jupyter notebook和一个完整的问答聊天机器人应用程序,以供参考。
什么是RAG以及它在问答聊天机器人中的角色
RAG,即检索增强生成,是一种通过整合超出初始训练集的补充数据来丰富语言模型(LLM)知识库的技术。尽管LLM在跨不同主题进行推理方面具有能力,但它们仅限于在特定截止日期之前训练的公共数据。为了使AI应用程序能够有效处理私有或更近期的数据,RAG通过按需补充特定信息来增强模型的知识。这是一种替代微调LLM的方法,微调可能会很昂贵。
在问答聊天机器人领域,RAG在处理非结构化数据查询中发挥着关键作用,包括两个主要组成部分:索引和检索/生成。
索引从数据源摄取数据开始,然后将其分割成更小、更易于管理的块以进行高效处理。这些分割的块随后被存储和索引,通常使用嵌入模型和向量数据库,确保在运行时能够快速准确地检索。
在检索和生成过程中,系统在接收到用户查询后,使用与索引阶段相同的嵌入模型生成嵌入向量,然后使用检索器组件从索引中检索相关数据块。这些检索到的段落随后传递给LLM以生成答案。
因此,RAG赋予了问答聊天机器人访问和利用结构化和非结构化数据源的能力,从而通过使用嵌入模型和向量数据库作为LLM微调的替代方案,增强了它们提供精确和最新用户查询响应的能力。
IRIS 向量搜索
InterSystems IRIS的向量搜索是一个新功能,它在数据库内启用了语义搜索和生成式AI能力。它允许用户根据数据的含义而不是原始内容来查询数据,利用了检索增强生成(RAG)架构。这项技术将非结构化数据(如文本)转换为结构化的向量,便于高效处理和响应生成。
该平台支持在关系模式中以压缩和高性能的向量类型(VECTOR)存储向量,允许与现有数据结构无缝集成。向量通过Embeddings表示语言的语义含义,相似的含义在高维几何空间中通过接近度反映出来。
通过使用点积(dot product)操作比较输入向量和存储的向量,用户可以确定两者的语义相似性,这非常适合信息检索等任务。IRIS还通过专用的向量数据类型提供高效的向量存储和操作,增强了对大型数据集操作的性能。
要利用这一能力,文本必须通过一系列步骤转换为嵌入,涉及文本预处理和模型实例化。InterSystems IRIS支持Python代码的无缝集成用于嵌入生成,以及ObjectScript用于数据库交互,使基于向量的应用实现顺畅。
你可以在这里查看更多有关向量搜索的文档和实例。
langchain-iris
简短的说,langchain-iris 是在 langchain 框架中使用 InterSystems IRIS 向量搜索的一种方式。
InterSystems IRIS 向量搜索与 langchain 的向量存储需求非常契合。IRIS 存储和检索embedding的数据,对于相似性搜索至关重要。凭借IRIS的 VECTOR 类型,IRIS 支持存储embeddings,使其可对非结构化数据进行语义搜索,并促进文档无缝处理到向量存储中。
通过利用点积比较等操作,IRIS 促进了语义相似性的比较算法,这对于 langchain 的相似性搜索需求也非常理想。
因此,langchain-iris 允许使用由 InterSystems IRIS 数据平台支持的 langchain 框架开发 RAG 应用程序。
有关 langchain-iris 的更多信息,请查看这里。
将 IRIS 作为 langchain 的向量存储目标
第一步,需要将langchain-iris导入
pip install langchain-iris
之后,可以使用 IRISVector 中的方法 from_documents() :
db = IRISVector.from_documents(
embedding=embeddings,
documents=docs,
collection_name=COLLECTION_NAME,
connection_string=CONNECTION_STRING,
)
其中:
embedding:设置langchain.embeddings的embeddings模型实例,比如OpenAI或hugging faces.
documents:是一系列字符串的数组,这些字符串将被应用于embedding模型,并且生成的向量将存储在IRIS中。通常,由于embedding模型的大小限制以及为了更好的管理,文档应该被分割;langchain框架提供了几种分割器。
collection_name:用于文档以及他的embedding 向量存储的表的名称
connection_string:用于连接IRIS的参数,通常使用下面的格式 iris://<username>:<password>@<hostname>:<iris_port>/<namespace>
在这里查看完整的使用 langchian-iris 的 hello world 代码。
进一步查看整个过程
首先,我们查看由langchain提供的原始版本的文档机器人示例。
这个原始示例中,使用了Chroma作为向量数据库:
from langchain_chroma import Chroma
…
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())
所以,我们这里修改使用IRIS 作为向量数据库:
vectorstore = IRISVector.from_documents(
embedding=OpenAIEmbeddings(),
documents=splits,
collection_name="chatbot_docs",
connection_string=iris://_SYSTEM:SYS@localhost:1972/USER',
)
你可以在这个jupter notebook里查看完整示例代码。
当运行完示例,我们可以在IRIS中查看由 langchain-iris 创建的表,表名由SQLUser包名以及collection_name中设置:
可以看到其中有四个字段组成:
id:文档id
dcoument:使用的文档或者将文档分割为文字块后传入的文字块
metadata:JSON对象包含了文档的相关信息
embedding::以embedding vector的方式保存的文档信息,这是IRIS的向量搜索功能中的VECTOR类型数据。
上面实现的是创建索引的过程。也就是langchain对每一个文档进行分割后,应用embedding 模型,并将其向量存储在IRIS中。
下一步,为了实现RAG应用,我们需要根据给定的查询字符串,在 IRIS 中查询最相关的文档,这是通过实现langchain框架中的检索器(retrievers)来实现的。
你可以使用下面的代码创建一个真对IRIS存储文档的检索器 (retriever):
retriever = vectorstore.as_retriever()
用这个检索器,您可以针对自然语言查询最相似的文档。langchain框架将使用索引步骤中使用的相同embedding模型从查询中提取向量。这样,就可以检索到与查询具有相似语义内容的文档片段。
为了举例说明,让我们使用langchain的例子,它索引了一个包含有关LLM(大型语言模型)代理信息的网页。这个页面解释了几个概念,比如任务分解。让我们看看,如果给定一个查询,比如“What are the approaches to Task Decomposition(任务分解的方法有哪些)?”,检索器会返回什么:
现在让我们执行一个语义上相同但句法上不同的查询,即使用具有相似含义的不同词语提问,来看看向量搜索引擎返回什么结果:
这里,我们可以看到即使传递不同的查询字符串,结果也几乎是相同的。这意味着嵌入向量在某种程度上抽象了文档和查询字符串中的语义。
为了进一步证明这种语义查询能力,现在让我们继续询问有关任务分解的问题,但这次询问它的潜在缺点:
可以看到,这次最相关的结果与之前的查询不同。此外,最初的结果中并没有直接出现“downside”这个词,但包含了一些相关词汇,如“challenges”(挑战)、“limitations”(限制)和“restricted”(受限)。
这加强了嵌入向量在向量数据库中进行语义搜索的能力。
检索步骤之后,最相关的文档被添加为上下文信息,与用户查询一起发送到LLM(大型语言模型)进行处理:
from langchain import hub
prompt = hub.pull("rlm/rag-prompt")
user_query = "What are the approaches to Task Decomposition?"
retrieved_docs = [doc.page_content for doc in retriever.invoke(user_query)]
example_messages = prompt.invoke(
{"context": "filler context", "question": user_query}
).to_messages()
print(example_messages[0].content)
这段代码将会生成提示词如下,可以看到,查询的返回结果作为上下文一起递交给LLM进行处理:
"""
You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.
Question: What are the approaches to Task Decomposition?
Context: Tree of Thoughts (Yao et al. 2023) extends CoT by exploring multiple ... (truncated in the sake of brevity)
Answer:
"""
于是,RAG应用可以在LLM提示词长度限制的情况下增强查询的准确度。
最后几句
总结来说,将IRIS向量搜索与langchain框架的集成为InterSystems开发者社区中的问答聊天机器人和其他依赖于语义搜索和生成式AI的应用程序的开发开辟了新的视野。
通过langchain-iris将IRIS作为向量存储的无缝集成简化了实现过程,为开发者提供了一个强大而高效的解决方案,用于管理和查询大量结构化和非结构化信息的数据集。
通过索引、检索和生成过程,由IRIS向量搜索驱动的RAG应用程序可以有效地利用公共和私有数据源,增强基于LLM的AI系统的能力,为用户提供更全面和最新的响应。
最后,如果您想更深入地了解并查看一个完整的应用程序实现这些概念,以及与其他功能如互操作性和业务主机一起,与OpenAI和Telegram等外部API通信,请查看我们的应用程序iris-medicopilot。
这种集成展示了如何利用先进的技术来构建智能系统,这些系统不仅能够理解和回应用户的查询,还能够与外部服务和API进行交互,提供更加丰富和动态的用户体验。随着技术的不断发展,我们可以期待看到更多创新的应用程序,它们将利用这些工具和框架来解决现实世界的问题。
公告
Michael Lei · 一月 7
我们已经有一段时间没有在开发者社区上发表关于嵌入式 Git 的文章了,我想借此机会更新一下今年我们完成的大量工作以及未来的工作计划。
背景信息
如果您要在 IRIS 上构建解决方案,并想要使用 Git,那就太棒了! 只需将 VSCode 与本地 Git 仓库结合使用,并将更改推送到服务器上即可,就是这么简单。
但在以下使用场景中该怎么办:
您与其他开发者在共享的远程开发环境中合作,并想要避免因同时编辑同一文件而影响彼此的工作
您使用位于管理门户中的编辑器来实现互操作性或业务智能,并希望对您的工作直接进行源代码控制,即使在本地容器中也希望如此
您仍在使用 Studio 处理一些任务并且/或偶尔会再次从 VSCode 跳转回 Studio;或者您的团队还没有完全接受 VSCode,一些团队成员仍想使用 Studio,而其他人在使用 VSCode
您同时在同一命名空间中处理多个独立的项目,例如使用 InterSystems Package Manager 定义的多个软件包,并想仅通过一个 isfs 编辑视图使用所有软件包(而不是在多个单独的项目中使用),同时在合适的本地 git 仓库中自动跟踪更改
在以上任何情况下,您都非常需要嵌入式源代码控制。 您可能听说过“服务器端源代码控制”或“源代码控制挂钩”这类叫法,它们的含义相同,都表示可在所有编辑器(包括 IDE 和图形编辑器)中对 IRIS 实例实现一致的源代码控制行为。 所有控制操作都是针对与您的 IRIS 实例位于同一位置的源代码控制仓库执行的,该仓库可能位于远程服务器上、您自己的机器上,甚至可能位于容器中。
如果您希望开始使用 Git 进行嵌入式源代码控制,可以先从嵌入式 Git (https://github.com/intersystems/git-source-control) 着手。 嵌入式 Git 不是 InterSystems 支持的产品,但得到了 InterSystems 内我的团队(应用程序服务团队)和广大用户社区的大力支持。 我们始终欢迎大家提出 PR 和 GitHub 议题,我们会监控开发者社区活动(特别是使用相对较新的“嵌入式 Git”标签)。
2024 年嵌入式 Git 工作回顾
2024 年初,我曾向已能轻松使用 Git 并愿意在必要时进行深入研究、更偏向技术型的用户推荐嵌入式 Git。 现在,我极力推荐所有人使用嵌入式 Git。 为了展示我们对此工具倾注的心血以及我们在 2024 年取得的飞跃,下方是过去几年的提交量图:
如果您想了解我们的最新动态,可以查看版本或我们的变更日志,但下面是对要点的总结:
7 月,我们添加了“基本模式”(具体说明请参阅此处),其中的“同步”操作可以简化拉取/提交/变基/推送工作流,我们推荐大家在一般情况下使用该模式,尤其是那些不太熟悉 Git 的用户。
在多个版本中,我们将 git 拉取和签出操作(实际上是任何修改 Git 仓库状态的操作)无缝同步回 IRIS,从而无需强制重新加载整个代码库便可确保所有内容均为最新状态。
在我们的 9 月版本中,通过从管理门户下载 VSCode 工作空间文件,您可以非常轻松地建立 isfs 连接。
在我们的 11 月版本中,可以通过扩展设置页面进行更多配置,无需在终端运行命令,并针对互操作性设置中的两种最常见(几乎一定会出现)的用例增加了智能合并冲突解决功能。
除了以上工作之外,我们还解决了数十个小错误和实用性问题,简化了管理门户的导航,并增加了很多小功能,以简化互操作性用例以及跨多个开发者特定命名空间在共享远程实例上的协作(我们认为这是一种常用方式,并推荐大家使用)。
即将推出
下一个版本 (2.8.0) 预计在两周内发布,其中将包含我们历经数月开发出的“生产分解”功能。 互操作性生产通常以单个文件的形式进行源代码控制,由于一次只能由一人编辑生产,这会导致并发问题。 共享开发环境中还存在一些合并问题,这些问题几乎一定会出现,虽然我们可以通过智能化方式解决它们,但在某些分支工作流中,这些问题很可能会继续出现。 利用生产分解功能,每个业务主机(服务、进程或操作)在源代码控制中都会以单个文件的形式表示。 如果您有兴趣尝试此功能,请联系我们!
进入 2025 年,我们将继续保持嵌入式 Git 的发展势头,重点关注其他身份验证方法并支持其他常见部署模式。 您可以访问 2025 H1 里程碑了解我们的大致计划(其中包括几次版本发布;我们通常会每月发布次要版本,并根据需要发布补丁版本修复重要错误)。
如果您有兴趣深入了解开发细节/获取最新开发信息,欢迎加入我们每周五召开的利益相关者会议。 此会议也成为了嵌入式 Git 的一种“办公时间”。 请随时留言告诉我您的电子邮件地址,我会邀请您加入会议。
问题
Yufeng Li · 十二月 23, 2021
在IRIS 上怎么实现读写分离? IRIS的镜像(Mirroring)支持多个报告类型(Reporting Asyncs)的异步成员,这些异步成员可以用于查询、报表运行、BI等多种场景。 我们现在是用前端调用rest api,这种情况下要怎么区分调用读服务器还是写服务器? 可以封装一个REST服务用于前端api调用,这个REST服务根据不同api操作和路径,在后台调用不同服务器上的REST API或SQL操作。或者也可以考虑使用InterSystems API管理器做这个事。 相关文章请参考:https://cn.community.intersystems.com/smartsearch?search=API 如果是指数据库层的读写分离,可以使用Sharding技术,利用Sharding技术中的计算结点和数据结点,搭建负载均衡+读写分离的数据库集群,参考:
https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=GSCALE_sharding#GSCALE_sharding_reference_plan_qs
如果服务器/实例资源有限,又想实现读负载与写负载的分离,那么基于@Qiao Peng指出的镜像异步成员,在API层(即应用程序层)通过业务流程来控制查询/写入操作的分发则是成本较低的方案。 请参考这个文档链接[Deploy Compute Nodes for Workload Separation and Increased Query Throughput](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GSCALE_sharding#GSCALE_sharding_options_qs)
文章
Michael Lei · 三月 12, 2022
在最近的大规模基准测试活动中,我们看到过多的%sys CPU时间,对应用程序的扩展产生了负面影响。
问题
我们发现,由于TZ环境变量没有被设置,很多时间都花在了localtime()系统调用上。 我们创建了一个简单的测试程序来证实这一观察结果,设置了TZ与未设置TZ的时间差和所需的CPU资源都是惊人的。 我们发现,当TZ没有设置时,从localtime()继承使用stat()系统调用到/etc/local_time是成本很高。
建议
InterSystems强烈建议在任何Linux安装中,无论是x86还是Linux on Power,都要确认TZ环境变量的设置是否适当,以获得最佳性能。 更多详情请见。"man tzset"。
目前的Caché 2016.1现场测试包含了对日期和时间功能的优化,初步测试表明有很大的改进。 下面是测试新的内部函数调用的样本输出,在这两种情况下,在Power上的Linux都没有设置TZ。
在Caché 2016.1 FT之前:
real 0m22.60s
user 0m1.64s
sys 0m20.89s
带有Caché 2016.1 FT:
real 0m0.40s
user 0m0.37s
sys 0m0.00s
请在评论区说明你的应用程序在TZ环境变量方面的任何经验,以及Caché 2016.1现场测试在设置或不设置TZ时的影响。谢谢!
文章
姚 鑫 · 四月 2, 2021
# 第十五章 使用管理门户SQL接口(一)
本章介绍如何在InterSystems IRIS®数据平台管理门户上执行SQL操作。
管理门户界面使用动态SQL,这意味着在运行时准备和执行查询。
Management Portal界面旨在帮助针对小型数据集开发和测试SQL代码。
它不打算用作在生产环境中执行SQL的接口。
管理门户还提供了各种配置SQL的选项。
有关使用管理门户的一般信息,请选择左上角的Help按钮。
通过使用左上角的Contact按钮,可以从管理门户向InterSystems Worldwide Response Center (WRC)报告有关InterSystems软件的问题。
# 管理门户SQL工具
InterSystems IRIS允许使用SQL工具从InterSystems IRIS管理门户检查和操作数据。
此操作的起点是Management Portal System Explorer选项。
从这里选择SQL选项。
这将显示SQL接口,它允许:
- 执行SQL查询—编写和执行SQL命令。
可以对现有的表和数据执行SQL查询,创建表,或插入、更新或删除表数据。
可以编写SQL代码直接转化为一个文本框(包括选择、插入、更新、删除、创建表和其他SQL语句),检索语句的SQL历史文本框,拖拽一个表到文本框来生成一个查询(`SELECT`语句),或构成一个查询(`SELECT`语句)使用`query Builder`接口。
- 过滤模式内容——在屏幕左侧显示当前名称空间的SQL模式或这些模式的过滤子集,以及每个模式的表、视图、过程和缓存查询。
可以选择单独的表、视图、过程或缓存查询来显示其目录详细信息。
- 向导—执行向导,以执行数据导入、导出或数据迁移。
执行向导以链接到表或视图,或链接到存储过程。
- Actions -定义一个视图;
打印一个表定义的详细信息;
通过运行调优表和/或重建索引提高查询的性能;
或者通过清除不需要的缓存查询和/或删除不需要的表、视图或过程定义来执行清理。
- 打开表格——以显示模式在表格中显示当前数据。
这通常不是表中的完整数据:记录的数量和列中的数据长度都受到限制,以提供可管理的显示。
- 工具——执行以下工具之一:SQL运行时统计、索引分析器、备用显示计划、生成报告、导入报告。
- 文档—允许查看SQL错误代码列表和SQL保留字列表。
如果选择了一个表,则允许显示类文档(该表的类引用页)。
## 选择命名空间
所有SQL操作都会在特定名称空间中进行。因此,必须首先指定要通过单击SQL接口页面顶部的 **“开关switch”** 选项要使用的命名空间。这将显示可用名称空间列表,可以从中进行选择。
可以设置管理门户默认命名空间。从管理门户选择系统管理,安全性,用户。单击所需用户的名称。这允许编辑用户定义。从“常规”选项卡中,从下拉列表中选择“启动命名”空间。单击“保存”。如果未选择启动命名空间,则会默认为%SYS.。
## 用户自定义
许多Management Portal SQL操作都是为每个用户自动定制的。
如果在Execute Query选项卡或SQL Statements选项卡中设置了筛选器、最大值、模式或其他选项,则此用户指定的值将保留以供将来使用。
当同一个用户激活管理门户时,将显示该用户先前的设置。
重新启动InterSystems IRIS返回所有选项为默认值。
没有自定义名称空间选择。
它恢复到用户定义启动名称空间。
# 执行SQL查询
从管理门户选择System Explorer,然后选择SQL。
在页面顶部选择带有Switch选项的名称空间;
这将显示可用名称空间的列表。
要执行SQL查询,有三个选项:
- Execute Query:写并执行SQL命令。
SQL命令可以是一个`SELECT`查询,也可以是一个InterSystems SQL DDL或DML语句;
语句执行时在InterSystems IRIS服务器上验证。
- Show History:收回以前运行的SQL语句,然后重新运行它,或者修改它,然后运行它。
列出所有已执行的语句,包括未成功执行的语句。
- 查询生成器:调用SQL查询生成器(它专门用于创建SELECT语句)。
在SQL Query Builder中,通过选择表、列、`WHERE`子句谓词和其他查询组件来创建SQL `SELECT`查询。
然后,可以通过单击Execute query来运行查询。
## 编写SQL语句
Execute Query文本框不仅允许编写`SELECT`和`CALL`查询,还允许编写大多数SQL语句,包括DDL语句(如`CREATE TABLE`)和DML语句(如`INSERT`、`UPDATE`和`DELETE`)。
可以在“执行查询”文本框中指定SQL代码:
- 将SQL代码键入(或粘贴)到文本框中。
SQL代码区域不给SQL文本着色,也不提供任何语法或存在验证。
但是,它确实提供了自动拼写验证。
可以使用X图标删除文本框的内容。
- 使用Show History列表选择前面的SQL语句。
选中的语句将复制到文本框中。
执行时,该语句移到Show History列表的顶部。
注意,Show History列出了之前执行的所有语句,包括那些执行失败的语句。
- 使用表拖放在文本框中构造SQL代码。
- 可以使用Query Builder(而不是Execute Query文本框)来指定和执行`SELECT`查询。
使用查询生成器执行的选择查询不会显示在“执行查询”中,也不会列出在“显示历史”中。
Execute Query文本框中的SQL代码可以包括:
- ?输入参数。如果指定输入参数,例如 `TOP ? or WHERE Age BETWEEN ? AND ?`,`Execute`按钮显示查询窗口的Enter参数值,其中每个输入参数的条目字段按查询中指定的顺序。
- 空白字符。可以指定多个空格,单个和多行返回。标签键已禁用;将代码复制到SQL代码区域时,现有选项卡将转换为单个空格。线返回和未保留多个空格。
- 注释。 SQL代码区域支持单行和多行注释。在Show历史显示中保留并显示注释。在Show Plan语句文本显示或缓存查询中未显示注释。
- 返回多个结果集的查询。
在文本框中编写SQL代码后,可以单击“显示计划”按钮查看SQL代码而不执行SQL代码。如果代码有效,则显示计划显示查询计划。如果代码无效,则显示计划显示SQLCode错误值和消息。还可以使用“显示计划”按钮显示最近执行的SQL代码的此信息。
要执行SQL代码,请单击“执行”按钮。
### 表拖放
可以通过从屏幕左侧的表列表(或视图列表)拖动表(或视图)来生成查询,并将其丢弃到执行查询文本框中。这在表中生成了选择的选项列表,以及指定表的表中的所有非隐藏字段。然后,可以进一步修改此查询并使用Execute按钮执行它。
还可以从屏幕左侧的过程列表中拖放过程名称。
## 执行查询选项
SQL执行界面具有以下选项:
- 具有`SELECT`的“选择模式下拉列表”指定查询应用于提供数据值(例如,在WHERE子句中)的格式,并在查询结果集中显示数据值。选项是显示模式(默认值),ODBC模式和逻辑模式。
具有插入或更新的选择模式下拉列表允许指定输入数据是否将从显示格式转换为逻辑存储格式。对于此数据转换,必须使用选择运行时的选择模式编译SQL代码。在执行时间时,必须将“选择模式”下拉列表设置为逻辑模式。
选择模式对于数据类型是有意义的,其逻辑存储格式与所需的显示格式(显示或ODBC)不同,例如Intersystems Iris日期和时间和Objectscript`%List`结构化数据。
- 最大字段允许限制从查询返回的数量数量。它可以设置为任何正整数,包括0.一旦设置MAX,除非显式更改,否则将该值用于会话持续时间的所有查询。默认值为1000.最大值为100,000,如果输入没有值(将MAX设置为NULL),则输入大于100,000或非数值的值,这是默认值。还可以使用顶部子句限制要返回的数据行数。 MAX对其他SQL语句没有影响,例如删除。
如果单击“更多”选项,则SQL执行界面将显示以下其他选项:
- 方言:SQL代码的方言。包括“IRIS”、“Sybase”和“MSSQL”。默认为IRIS。
在InterSystems Transact-SQL (TSQL)迁移指南中描述了Sybase和MSSQL。
请注意,下次访问管理门户时,选择的方言将成为用户自定义的默认语言。
- 行号:一个复选框,指定是否在结果集中显示的每一行中包含行计数号。
行号是分配给结果集中每一行的连续整数。它只是对返回的行进行编号,它既不对应rowwid也不对应`%VID`。行号列标题名是#。默认是显示行号。
所有这些选项都是用户自定义的。
## 显示计划按钮
Show Plan按钮在页面的文本框中显示语句文本和查询计划,包括查询的当前查询计划的相对成本(开销)。可以从Execute查询或Show History接口调用Show Plan。查询计划是在准备(编译)查询时生成的;
当编写查询并选择Show Plan按钮时,就会发生这种情况。不必执行查询来显示其查询计划。Show Plan在为无效查询调用时显示`SQLCODE`和错误消息。
## SQL语句的结果
在“执行查询”文本框中编写SQL代码之后,可以通过单击“执行”按钮来执行代码。这要么成功执行SQL语句并在代码窗口下面显示结果,要么SQL代码失败。如果SQL代码失败,它会在code窗口下面显示一条错误消息(红色);
按下Show Plan按钮将显示`SQLCODE`错误和错误消息。
执行查询SQL代码执行作为后台进程执行。在执行代码时,Execute按钮被Cancel按钮替换。这允许取消长时间运行的查询的执行。
### 查询数据显示
如果选中了行号框,结果集将作为表返回,行计数器将显示为第一列(`#`)。
其余的列将按照指定的顺序显示。RowID (ID字段)可以显示或隐藏。每个列都由列名(如果指定了,也可以是列别名)标识。聚合、表达式、子查询、主机变量或文字选择项可以由列别名(如果指定)标识,或者由单词`Aggregate_`、`Expression_`、`Subquery_`、`HostVar_`或`Literal_`后跟选择项序列号(默认情况下)标识。
如果行列不包含数据(`NULL`),结果集将显示一个空白的表格单元格。
指定一个空字符串文本将显示一个`HostVar_`字段,其中包含一个空白的表格单元格。
指定`NULL`显示一个带有空白单元格的`Literal_`字段。
如果选择的字段是日期、时间、时间戳或%List编码的字段,则显示的值取决于显示模式。
以下显示特性是管理门户SQL接口独有的,执行查询结果显示和打开表数据显示:
- 数据类型`%Stream.Globalcharacter`的流字段将实际数据(最多100个字符)作为字符串显示。如果流字段中的数据长于100个字符,则显示数据的前100个字符,后跟省略的省略号(`...`)。
- 数据类型`%Stream.GlobalBinary`作为的流字段。
- 字符串数据字段根据需要,以完整的方式显示实际数据。
- Integer字段在结果表单元格中右对齐。 `ROWID`,`NUMERIC`和所有其他字段都是左对齐的。
当使用动态SQL代码,SQL Shell或嵌入式SQL代码执行相同的查询时,不会发生这些结果显示功能。
如果指定的查询返回多个结果集,则执行查询将这些结果集显示为命名选项卡:`Result #1`, `Result #2`等。
### 查询执行指标
如果成功,则执行查询显示性能信息和缓存查询例程的名称。如果显示数据以显示,则显示在性能信息下方。执行信息包括行计数,性能,缓存查询,显示缓存的查询名称,最后更新指定查询的最后一次执行的时间戳。
- Row count:对于`CREATE TABLE`这样的DDL语句,如果操作成功,则显示`Row count: 0`。
对于`INSERT`、`UPDATE`或`DELETE`等DML语句,显示受影响的行数。
对于`TRUNCATE TABLE`语句,快速`TRUNCATE`操作不能确定实际删除的行数,而是设置行数:-1。
对于`SELECT`,显示作为结果集返回的行数。注意,返回的行数由Max设置控制,它可能低于可以选择的行数。
对于多个结果集,列出每个结果集的行数,用/字符分隔。
指定一个或多个聚合函数(且没有选择字段)的查询总是显示`Row count: 1`,并返回表达式、子查询和聚合函数的结果,即使`FROM`子句表不包含行。
一个不指定聚合函数和不选择行的查询总是显示`Row count: 0`并且不返回结果,即使该查询只指定不引用`FROM`子句表的表达式和子查询。
带`no FROM`子句的查询总是显示`行数:1`,并返回表达式、子查询和聚合函数的结果。
- 性能:以运行时间(以秒为单位)、全局引用总数、执行的命令总数和磁盘读取延迟(以毫秒为单位)来衡量。
如果该查询存在缓存的查询,那么这些性能指标将用于执行缓存的查询。
因此,查询的第一次执行将比后续执行具有更高的性能指标。
如果指定的查询返回多个结果集,那么这些性能指标就是所有查询的总和。
要更深入地分析这些性能指标,可以运行`MONLBL`(逐行监视实用程序)并使用星号通配符`%sqlcq*`指定例程名称。
请参考使用`^%SYS.MONLBL`检查例程性能。
- 缓存查询:自动生成的缓存查询类名。
例如,`%sqlcq.USER.cls2`表示用户名称空间中的第二个缓存查询。
每个新的查询被分配一个新的缓存的查询名称,该名称具有下一个连续的整数。
通过单击此缓存查询名称,以显示关于缓存查询的信息,以及显示其显示计划或执行缓存查询的进一步链接。
关闭管理门户或停止InterSystems IRIS不会删除缓存的查询或重置缓存的查询编号。
要从当前命名空间中清除缓存的查询,请调用%`SYSTEM.SQL.Purge()`方法。
并不是所有的SQL语句都会导致缓存的查询。与现有缓存查询相同的查询,除了文字替换值(例如`TOP`子句值和谓词文字)之外,不会创建新的缓存查询。有些SQL语句是不缓存的,包括DDL语句和权限分配语句。
非查询SQL语句,如`CREATE TABLE`,也会显示缓存的查询名。
然而,这个缓存的查询名称被创建然后立即删除;
下一个SQL语句(查询或非查询)重用相同的缓存查询名称。
- 最后一次更新:最后一次执行查询(或其他SQL操作)的日期和时间。
这个时间戳在每次执行查询时都被重置,即使在重复执行相同的查询时也是如此。
- 成功执行还提供了一个打印链接显示打印查询窗口,它给你选择打印或导出到一个文件中查询文本和/或查询的结果集。点击查询和结果切换使可以显示或隐藏文本或查询结果集的查询,查询结果集显示包含名称空间的名字,结果集的数据行数,一个时间戳,缓存的查询名称。
(注意,时间戳是调用Print查询窗口的时间,而不是执行查询的时间。)
“打印查询”按钮用于打印查询窗口的屏幕截图。
“导出到文件”复选框显示指定导出文件格式(`xml、hdml、pdf、txt、csv`)和导出文件路径名的选项。
Export选项忽略查询和结果切换,并始终只导出结果集数据(默认为`:exportQuery.pdf`)和行数(默认为`:exportQueryMessages.pdf`);
不包括查询文本、名称空间、时间戳和缓存的查询名称。
如果不成功,则Execute Query显示错误消息。
可以单击Show Plan按钮来显示相应的`SQLCODE`错误值和消息。
## 显示历史
单击“显示历史记录”可列出当前会话期间执行的SQL语句。
Show History列出从该接口调用的所有SQL语句,包括那些成功执行和那些执行失败的语句。
默认情况下,SQL语句按执行时间列出,最近执行的语句出现在列表的顶部。可以单击任何列标题,根据列值按升序或降序排列SQL语句。从Show History列表中执行SQL语句将更新其执行时间(本地日期和时间戳),并增加其计数(执行次数)。
可以过滤Show History列表,如下所示:在过滤框中指定一个字符串,然后按Tab键。只有包含该字符串的历史项才会包含在刷新后的列表中。
筛选器字符串可以是在SQL语句列中找到的字符串(比如表名),也可以是在执行时间列中找到的字符串(比如日期)。
过滤字符串不区分大小写。
在显式地更改过滤器字符串之前,它将一直有效。
通过选择语句,可以在“Show History”中修改和执行SQL语句,该语句将显示在“execute Query”文本框中。
在“执行查询”中,可以修改SQL代码,然后单击“执行”。
对从Show History中检索到的SQL语句进行任何更改,都会将其作为新语句存储在Show History中;
这包括不影响执行的更改,如更改字母大小写、空格或注释。
空格不会显示在Show History中,但是当从Show History中检索SQL语句时,会保留空格。
通过单击Show History列表中SQL语句右侧的execute按钮,可以直接从Show History列表中执行(重新运行)未修改的SQL语句。
注意,Show History列表与缓存查询列表不同。
Show History列出当前会话中调用的所有SQL语句,包括那些在执行过程中失败的语句。
## 其他SQL接口
InterSystems IRIS支持许多其他编写和执行SQL代码的方法,在本手册的其他章节中有描述。
这些包括:
- 嵌入式SQL:嵌入ObjectScript代码中的SQL代码。
- 动态SQL:使用%SQL。
语句类方法(或其他结果集类方法)用于从ObjectScript代码中执行SQL语句。
- SQL Shell:在终端使用SQL Shell接口执行动态SQL。
文章
姚 鑫 · 七月 26, 2023
# 第三章 HL7 架构和可用工具 - 使用 HL7 架构结构页面
## 使用 HL7 架构结构页面
通过 `HL7` 架构页面,可以导入和查看 `HL7` 版本 `2` 架构规范。要显示此页面,请从主页中选择互操作性 > 互操作 > HL7 v2.x > HL7 v2.x 架构结构。有关使用此页面的一般信息,请参阅在产品中使用虚拟文档中的“使用架构结构页面”。
`HL7` 模式页面提供了一个附加选项卡:消息类型。此选项卡将两个消息结构标识为请求/响应对。
## 查看文档类型列表
要列出某个类别中的所有文档类型结构,请首先选择该类别,然后单击“`DocType` 结构”选项卡。
## 查看消息结构
要查看消息结构的内部组织,请从 `HL7` 架构页面上的 `DocType` 结构选项卡单击其名称(选择互操作性 > 互操作 > HL7 v2.x > HL7 v2.x 架构结构)。 `InterSystems` 产品使用以下视觉提示和命名约定在“结构”部分中显示消息的段结构。
- 组成消息结构的段按从上到下的顺序列出。
- 段名称必须全部大写。
- 显示每个消息段的三个字母名称:`MSH`、`NTE`、`PID` 等。该名称指示 `HL7` 消息结构中该位置存在的段类型。包含选项、重复或包含一组其他段的段的名称会在名称中附加特殊字符。
- 绿色虚线包围可选的段、组或字段。
- 可以重复的段在段名称后附加了括号。例如,如果`PID`段可以重复,则出现`PID()`。
- 包含其他段选择的段被视为段的联合。这些联合段的段名称后附加有“`union`”一词。只有联合中包含的段之一可以出现在消息结构内的该位置。
- 包含一组段的段在段名称后附加了字母“`grp`”。要展开或折叠组,请使用组名称旁边的箭头图标。
- 双击段名称可在单独的窗口中打开该段的结构。
## 查看段结构
要查看消息段的结构,请在与上一节中显示的示例类似的任何页面中单击其名称。 `InterSystems` 产品显示一个表格,其中列出了该段中的所有字段。这是 `HL7` 架构段结构页面。
例如,如果单击 `2.3:ADT_A01` 消息结构中的 `PR1` 段,`InterSystems` 产品将显示以下页面。
各列如下:
- `Field` 字段 — 用于访问段内字段的数字。
- `Description` 描述 — 字段的简短描述。
- `Property Name` 属性名称 — 用于访问段内字段的名称。
- `Data Structure` - 对于使用数据结构的更复杂的字段值,需要进一步的语法详细信息才能完成`segment:field` 虚拟属性路径。可以通过单击此列中的名称来获取此信息
- `Symbol` 符号——表示字段的语法规则。此列中的字符指示是否可以预期此字段在消息段中存在、不存在或重复。可能的值
Symbol |Meaning
---|---
`!`| (仅限`1`)该字段为必填字段;它只能出现一次。
`?`| (`0`或`1`)该字段是可选的,但如果发生,则可能只出现一次。
`+`| (`1`个或多个)该字段可以重复一次或多次。
`*`| (`0`或更多)该字段可以重复`0`次或多次。
`&`| 该字段可能存在,并且可能重复,但仅在某些条件下。
`n*`| `0` 到 `n`) 该字段最多重复 `n` 次。
- `Repeat Count` - 该字段可以重复的最大次数(如果重复,并且有最大值)。
- `Minimum Length` - 字段中的最小字符数。该字段的每次重复都必须包含此数量的字符。
- `Maximum Length` - 字段中的最大字符数。该字段的每次重复都可以包含此数量的字符。
- `Required` - 显示 `R` 表示必需,`O` 表示可选。
- `Repeating` - 显示 `1` 表示 `true`,`0` 表示 `false`。
- `Code Table` - 单击条目可查看可在此字段中输入的有效代码。
- `Alternate Description`替代描述 - 该领域的第二个更长的描述。
可以使用此信息(尤其是“属性名称”列)以“段:字段”格式构建虚拟属性路径。以下是涉及 `2.3:ADT_A01` 消息结构中 `PR1` 段的简单字段值的虚拟属性路径示例。 `()` 快捷语法指示重复字段的所有可用实例,而 `(1)` 指示第一个实例:
```java
PR1grp().PR1:ProcedureType
PR1grp().PR1:ProcedureCode()
PR1grp().PR1:ProcedureCode(1)
PR1grp().PR1:ProcedureCode(x)
PR1grp().PR1:ProcedurePriority
```
文章
Hao Ma · 一月 30, 2021
## 检查Apache工作状态
确认Apache正常工作, apache的版本已经安装路径。
[root@centos7 ~]# httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built: Apr 24 2019 13:45:48
[root@centos7 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2020-06-15 16:46:36 CST; 5min ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 6506 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
Tasks: 272
Memory: 31.3M
CGroup: /system.slice/httpd.service
├─6506 /usr/sbin/httpd -DFOREGROUND
├─6592 /usr/sbin/httpd -DFOREGROUND
├─6607 /usr/sbin/httpd -DFOREGROUND
├─6608 /usr/sbin/httpd -DFOREGROUND
├─6609 /usr/sbin/httpd -DFOREGROUND
├─6610 /usr/sbin/httpd -DFOREGROUND
├─6611 /usr/sbin/httpd -DFOREGROUND
├─6612 /usr/sbin/httpd -DFOREGROUND
├─6613 /usr/sbin/httpd -DFOREGROUND
├─6622 /usr/sbin/httpd -DFOREGROUND
├─6623 /usr/sbin/httpd -DFOREGROUND
└─6633 /usr/sbin/httpd -DFOREGROUND
Jun 15 16:46:36 centos7 systemd[1]: Starting The Apache HTTP Server...
Jun 15 16:46:36 centos7 systemd[1]: Started The Apache HTTP Server.
[root@centos7 ~]#
确认httpd.conf的位置。 在CentOS7中此位置为/etc/httpd/conf, 其他linux系统可能有其他位置, 如果不确认,可以使用 find命令寻找.
[root@centos7 ~]# ll /etc/httpd/conf
total 56
-rw-r--r-- 1 root root 890 Jun 26 2019 healthshare.conf
-rw-r--r-- 1 root root 0 Jun 26 2019 healthshare.conf_save
-rw-r--r-- 1 root root 11786 Jun 30 2019 httpd.conf
-rw-r--r-- 1 root root 11753 Jun 26 2019 httpd.conf.bak
-rw-r--r-- 1 root root 11746 Jun 30 2019 httpd.conf2
-rw-r--r-- 1 root root 13077 Apr 24 2019 magic
[root@centos7 ~]#
从Caché所在服务器用浏览器检查Apache测试页面可以访问。如果在Apache本地服务器访问, 网址为127.0.0.1(如果远端无法访问,请首先检查防火墙,后面步骤中有介绍)
picture testing123
## 关闭SELinux配置
查询确认SELinux状态为disabled
[root@centos7 ~]# getenforce
Disabled
如果非disabled状态,需要修改配置文件实现, 下图为修改后的文件内容,修改后重启电脑生效。
[root@centos7 ~]# cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
[root@centos7 ~]#
## 检查防火墙
确认apache所在服务器的防火墙打开了80端口。(为简化步骤, 这里不讨论Web Server的SSL接入)
[root@centos7 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2020-06-15 17:24:15 CST; 2s ago
Docs: man:firewalld(1)
Main PID: 27433 (firewalld)
Tasks: 2
Memory: 25.1M
CGroup: /system.slice/firewalld.service
└─27433 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
Jun 15 17:24:15 centos7 systemd[1]: Starting firewalld - dynamic firewall daemon...
Jun 15 17:24:15 centos7 systemd[1]: Started firewalld - dynamic firewall daemon.
[root@centos7 ~]# firewall-cmd --state
running
[root@centos7 ~]# firewall-cmd --zone=public --list-ports
[root@centos7 ~]# firewall-cmd --zone=public --add-port=80/tcp --permanent
Success
[root@centos7 ~]# firewall-cmd --reload
success
[root@centos7 ~]# firewall-cmd --zone=public --list-ports
80/tcp
[root@centos7 ~]
如果Caché安装在另一台服务器, Web gateway和Caché间的通信通过Caché的superserver端口(默认1972), 因此Caché所在服务器的防火墙必须运行此端口访问。
## 对Apache调优
如果apache的工作模式为Prefork, 通过修改配置文件后重启服务,将工作模式改成“worker”(下面cat命令显示修改后的配置文件)
[root@centos7 ~]# apachectl -V | grep MPM
Server MPM: prefork
[root@centos7 ~]# vim /etc/httpd/conf.modules.d/
[root@centos7 ~]# cat /etc/httpd/conf.modules.d/00-mpm.conf
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:
# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
LoadModule mpm_worker_module modules/mod_mpm_worker.so
# Worker MPM parameters
ServerLimit 40
StartServers 10
MaxRequestWorkers 1000
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
#LoadModule mpm_event_module modules/mod_mpm_event.so
[root@centos7 ~]# systemctl restart httpd
[root@centos7 ~]# apachectl -V | grep MPM
Server MPM: worker
[root@centos7 ~]#
## 安装Web Gateway
最新的IRIS或者HealthConnect安装包可能不包含让用户选择是否安装csp/web gateway的选项, 因此大多数情况, 用户更多的是使用专门的Web/CSP gateway的安装包来安装, 无论Apach Server 和Caché/IRIS Server是否在同一台服务器上。
以下的介绍是用WebGateway 2020.1版本安装的过程。
1. 解压缩安装包到一个临时文件夹
[root@centos7 ~]# tar -xzf WebGateway-2020.1.0.197.0-lnxrhx64.tar.gz
2. 使用touch命令在/etc/httpd/conf.d目录下创建空配置文件isc.conf
Apaceh启动时会调用主配置文件/etc/httpd/conf/httpd.conf。 该文件的默认配置项中会自动include目录/etc/httpd/conf.d下的*.conf文件, 因此不同的应用创建不同的conf文件放在conf.d目录下是方便管理的通常做法。 这个.conf的文件名可以任意名字,isc.conf只是示意。(下一步安装Web Gateway时需要输入此名字)。
[root@centos7 httpd]# touch /etc/httpd/conf.d/isc.conf
同理手动 在 /opt/webgateway/bin 下面建立CSP.ini文件,并且赋予读写权限
3. 到解压后的安装包目录下的install子目录, 执行以下命令:
[root@centos7 ~]# cd WebGateway-2020.1.0.197.0-lnxrhx64/
[root@centos7 WebGateway-2020.1.0.197.0-lnxrhx64]# ls
install lnxrhx64
[root@centos7 WebGateway-2020.1.0.197.0-lnxrhx64]# cd install/
[root@centos7 install]# ./GatewayInstall
Starting Web Gateway installation procedure.
Please select WebServer type. Choose "None" if you want to configure
your WebServer manually.
1) Apache
2) None
WebServer type? [2] 1
Please enter location of Apache configuration file [/etc/httpd/conf/httpd.conf]: /etc/httpd/conf.d/isc.conf
Enter user name used by Apache server to run its worker processes :
Please enter location of Apache executable file :
Apache version 2.4 is detected.
Please enter destination directory for Web Gateway files [/opt/webgateway]:
Do you want to create directory /opt/webgateway [Y]:
Please enter hostname of your InterSystems IRIS server [localhost]: HCDEMO
Please enter superserver port number for your InterSystems IRIS server [51773]:
Please enter InterSystems IRIS configuration name [IRIS]: HCDEMO (注 这里的 configuration name 其实是csp.ini 中服务器的配置代称,可以任意起,不一定必填为服务器本身的hostname)
Please enter directory for static CSP content [/opt/webgateway/hcdemo]:
Do you want to create directory /opt/webgateway/hcdemo [Y]:
Installing InterSystems IRIS Web Gateway for Apache:
------------------------------------------------------------------
Apache configuration file: /etc/httpd/conf.d/isc.conf
InterSystems IRIS configuration name: HCDEMO
InterSystems IRIS server address: HCDEMO
InterSystems IRIS server port number: 51773
Web Gateway installation directory: /opt/webgateway
------------------------------------------------------------------
Do you want to continue and perform the installation [Y]:
Updating Apache configuration file ...
- /etc/httpd/conf.d/isc.conf
* You need to restart your Apache server before any
configuration changes will take effect.
Web Gateway configuration completed!
[root@centos7 install]#
安装结束后
- 检查安装目录被生成,并包含CSPGateway文件
- 检查isc.conf文件,确认文件已经被写入配置信息。
- 登录CSP Gateway管理页面查看: http://WebServer:80/csp/bin/Systems/Module.cxw
如果不是在Apache服务器访问而是远程登录该页面,此时会出现错误提示,显示CSP Gateway的版本信息和“You are not authorized to use this facility”的提醒。这是CSP Gateway的安全策略。默认不允许远程的访问,对于需要远程访问的源IP地址或者源网段,用户必须手工在CSP.ini配置文件的[SYSTEM]块里添加,比如添加 ”System_Manager=172.16.58.100",或者"System_Manger=172.16.*.*"。虽然不推荐,但"System_Manager=*.*.*.*”允许任意地址远程访问的远程访问。如果CSP.ini没有自动生成,那需要手动 在 /opt/webgateway/bin 下面建立此文件,并且赋予读写权限。 下面是添加System_Manager后的CSP.ini例子:
[root@centos7 bin]# cat /opt/webgateway/bin/CSP.ini
[SYSTEM_INDEX]
HCDEMO=Enabled
LOCAL=Enabled
[HCDEMO]
Ip_Address=HCDEMO
TCP_Port=51773
Minimum_Server_Connections=3
Maximum_Session_Connections=6
[APP_PATH_INDEX]
/=Enabled
/csp=Enabled
/hcdemo=Enabled
[APP_PATH:/]
Default_Server=HCDEMO
Alternative_Server_0=1~~~~~~HCDEMO
[APP_PATH:/csp]
Default_Server=HCDEMO
Alternative_Server_0=1~~~~~~HCDEMO
[APP_PATH:/hcdemo]
Default_Server=HCDEMO
Alternative_Server_0=1~~~~~~HCDEMO
[SYSTEM]
SM_Timeout=28800
Server_Response_Timeout=60
No_Activity_Timeout=86400
Queued_Request_Timeout=60
Configuration_Initialized=Tue Nov 17 07:58:29 2020
Configuration_Initialized_Build=2001.1740
System_Manager=*.*.*.*
[LOCAL]
Ip_Address=127.0.0.1
TCP_Port=1972
Minimum_Server_Connections=3
Maximum_Session_Connections=6
[root@centos7 bin]#
## 登录Web Gateway管理页面的抓图
检查Web Gateway的配置文件位置,版本,log位置
## 配置CSP Gateway到IRIS的连接,并测试从Apache登录IRIS维护界面
### 在CSP Gateway配置页面,查看Server Access。
Server Access中会列出这本CSP Gateway连接的IRIS实例的列表。在上面的安装步骤中,当问到了“ Please enter hostname of your InterSystems IRIS server [localhost]: HCDEMO ”选择了HCDEMO, 这时这个列表中会显示有两个Server, localhost和HCDEMO. (localhost无法被删除,遗憾)
下面检查HCDEMO Server的配置
- 检查服务器地址为127.0.0.1
- 添加到Caché服务器的账号密码,默认为CSPSystem, SYS
如果IIS服务器+Web Gateway和Caché位于两个不同的服务器, 或者需要添加到另一Caché Server的连接, 需要添加Server, 如下图,
需要的配置: Caché服务器的IP,superserver端口号, CSPSystem用于的密码,服务器的类型(可选)
**测试Caché Server连接成功**
双击左边菜单栏的"Test Server Connection", 确认结果中收到"Server connection test was successful: ...."的结果。
## 访问IRIS维护主页 (可选)
从链接 http://WebServer/csp/sys/Utilhome.csp 访问IRIS维护主页System Management Portal应该可以成功了,但您会发现有部分网页内容(element)无法加载。这是因为在默认的安装中,isc.conf中CSP Gateway路径的配置的"CSPFileTypes csp cls zen cxw"中只将这4种类型的请求发送给CSP Gateway, 而被称为Static file的文件,比如.js, .css, .png等等类型的文件并没有被发送给CSP Gateway. 这是另外的一个安全机制,强制客户人工的配置是否需要从Web服务器访问IRIS维护主页。如果答案是NO, 那么访问IRIS维护页面就只能通过PWS,用IRIS服务器的52773的接口。 如果用户认为从Web服务器访问IRIS维护页面是必要的, 需要修改CSPFileTypes配置,比如修改成"CSPFileTypes *",作用是把任意类型的请求发送给IRIS。以下是安装并修改后的isc.conf文件示例。
[root@centos7 conf.d]# cat isc.conf
#### BEGIN-ApacheCSP-SECTION ####
LoadModule csp_module_sa "/opt/webgateway/bin/CSPa24.so"
CSPModulePath "/opt/webgateway/bin/"
CSPConfigPath "/opt/webgateway/bin/"
Alias /csp/ "/opt/webgateway/hcdemo/csp/"
SetHandler csp-handler-sa
SetHandler csp-handler-sa
CSPFileTypes *
AllowOverride None
Options MultiViews FollowSymLinks ExecCGI
Require all granted
Require all denied
AllowOverride None
Options None
Require all granted
Require all denied
#### END-ApacheCSP-SECTION ####
#### BEGIN-ApacheCSP-SECTION-HCDEMO ####
Alias /hcdemo/csp/ "/opt/webgateway/hcdemo/csp/"
#### END-ApacheCSP-SECTION-HCDEMO ####
[root@centos7 conf.d]#
注意isc.conf修改后需要重启apache server
[root@centos7 conf.d]# systemctl restart httpd
[root@centos7 conf.d]#
## 访问IRIS上的其他Web Application
IRIS上其他的Web Application需要经过配置才可以发送到IRIS Server。这些Web Application可能是一个访问HTTP, REST的URL, 或者是一个用户自己定义的SOAP,甚至可能是一个简单的CSP文件。要确保他们被发送给IRIS Server, 用户需要:
1. 配置Apache配置文件isc.conf, 保证请求被发送给了CSP Gateway。 可以通过CSP Gateway管理页面的HTTP Trace来确认。
2. 如果需要,配置CSP Gateway, 将请求发送给IRIS.
### 访问带文件后缀的应用
在isc.conf中的中定义的是Web Server中文件对象的地址,比如"/opt/webgateway/bin/"是CSP Gateway的.so文件的存放位置。 Alias是URL中资源地址,比如"/csp/"到定义的映射。他们在apache中注册一个有后缀的文件的发送路径, 这个配置使得访问"http://WebServer/csp/sys/Utilhome.csp"可以成功发送给CSP Gateway。
Alias /csp/ "/opt/webgateway/hcdemo/csp/"
CSPFileTypes *
AllowOverride None
Options MultiViews FollowSymLinks ExecCGI
Require all granted
Require all denied
对于其他的Web Application, 比如如果需要将"http://WebServer/test/Hello.csp"成功发送给CSP Gateway, 需要添加以下配置,它把路径为”/test/"的URL发送给CSP Gateway处理。
Alias /test/ "/opt/webgateway/hcdemo/csp/"
测试连接一个SOAP服务,注意这个服务要在IRIS的Web Applicatin里配置正确,它至少可以从PWS用匿名用户访问。(关于Web Application的配置另行文档, 简单说, 要匿名访问, 要使用%Security_WebGateway的资源).测试结果:
[root@centos7 conf.d]# curl http://172.16.58.100/test/test.webservice1.cls?soap_method=winter
Winter is Coming...
[root@centos7 conf.d]#
### 访问其他URL应用
对于 “http://172.16.58.100/api/mgmnt/v2/”这样的URL地址, 映射到CSP Gateway处理需要的配置是。下面的配置保证对"/api/"开头的,没有文件地址的URL的处理:
SetHandler csp-handler-sa
CSP on
请求的结果如下:
[root@centos7 ~]# curl -X GET "http://172.16.58.100/api/mgmnt/v2/"
[{"name":"%Api.IAM.v1","webApplications":"/api/iam","dispatchClass":"%Api.IAM.v1.disp","namespace":"%SYS","swaggerSpec":"/api/mgmnt/v2/%25SYS/%25Api.IAM.v1"},{"name":"%Api.Mgmnt.v2","webApplications":"/api/mgmnt","dispatchClass":"%Api.Mgmnt.v2.disp","namespace":"%SYS","swaggerSpec":"/api/mgmnt/v2/%25SYS/%25Api.Mgmnt.v2"},{"name":"PetStore","dispatchClass":"PetStore.disp","namespace":"DEMO","swaggerSpec":"/api/mgmnt/v2/DEMO/PetStore"}][root@centos7 ~]#
备注: 如果得到了{"msg":"错误 #8754: Unable to use namespace: USER."},或者403 forbidden, 需要在IRIS上给Web Application "/api/mgmnt"添加”%DB_USER"的权限;或者,也可以将应用的“安全设置”设成"密码",然后使用下面的命令查看:
[root@centos7 conf.d]# curl -i -X GET http://172.16.58.100/api/mgmnt/v2/ -u "_system:SYS"
HTTP/1.1 200 OK。。。(后面省略)
[{"name":"%Api.IAM.v1","webApplications":"/api/iam","dispatchClass":"%Api.IAM.v1.disp","namespace":"%SYS","swaggerSpec":"/api/mgmnt/v2/%25SYS/%25Api.IAM.v1"},{"name":"%Api.Mgmnt.v2","webApplications":"/api/mgmnt","dispatchClass":"%Api.Mgmnt.v2.disp","namespace":"%SYS","swaggerSpec":"/api/mgmnt/v2/%25SYS/%25Api.Mgmnt.v2"},{"name":"PetStore","dispatchClass":"PetStore.disp","namespace":"DEMO","swaggerSpec":"/api/mgmnt/v2/DEMO/PetStore"}][root@centos7 conf.d]#
### CSP Gateway配置 "Application Access"
通常情况下,CSP Gateway测试成功连接IRIS Server后,会发现IRIS上的Web Application列表,并添加到自己的”APPlicaiton Access"列表里。如下图所示。每次用户在IRIS添加一个新的Web应用, 只需要在isc.conf上做相应的配置,无需人工去更新CSP Gateway的配置。
特殊的情况,如果发现某个URL无法发送到IRIS。先打开了CSP Gateway的HTTP Trace,确认CSP Gateway可以收到请求消息但无法发送到IRIS, 这是需要人工检查并且配置"Application Access".
文章
Claire Zheng · 九月 9, 2021
在医院信息化领域,中日联谊医院最近一次站在行业瞩目的聚光灯下,是在2021年7月。在国家卫生健康委统计信息中心发布的《关于2020年度国家医疗健康信息互联互通标准化成熟度测评结果公示的通知》中,9家医院获评五级乙等,中日联谊医院名列其中。这也是目前为数不多的“通关”互联互通五乙的医院之一。2021年是《国家医疗健康信息医院信息互联互通标准化成熟度测评方案(2020年版)》(以下简称新版测评方案)施行的第一个年头。由于测评方案的细化、参评机构的数量增多,业界普遍反映医院互联互通测评的整体难度正在逐年增大。而五级乙等,已是医疗机构目前所能取得的最高级别。
在互联互通新版测评方案中,对互联互通功能的“实际落地”与“有效应用”提出了很高的要求。在五级乙等的分级要求中就明确提出:“实现公众服务应用功能数量不少于27个、医疗服务应用功能数量不少于30个;提供较为完善的互联网诊疗服务,初步实现基于平台的临床决策支持、闭环管理、大数据应用。”
医院信息化建设立足于实际应用,为医院的医疗服务与运营管理提供助力,这是中日联谊医院能够获评五级乙等的重要原因之一。
医院在参与测评的过程中,遇到的首要问题即异构系统的接入问题。互联互通新版测评方案对医院信息系统内外联通业务的数量提出了明确要求,其中对五级乙等的分级要求是:集成平台至少需要接入54个内部业务系统,以及不少于7个外部机构数量,实现基于平台的内部与外部联通业务。
为达到上述要求,医疗机构需有效解决异构系统间的数据交互问题,完成交互服务接口和闭环管理改造。中日联谊医院采用了“东华医为医院信息平台产品”,该产品依托InterSystems技术实现,是互联互通标准化成熟度测评工作的基础。InterSystems数据平台技术不仅稳定可靠,有效支撑数百万级的大规模消息吞吐交换,而且以其强大的可扩展性、易用性和互操作能力,使各异构系统的直接连接更简单,降低了交互服务接口开发的时间和成本,帮助医院高质、高效地推进了业务联通工作。
点击此次,阅读全文
文章
Michael Lei · 六月 6, 2023
大家好!
我相信很多人都希望出席 2023 年全球峰会,但出于某种原因无法出席。以下是对 6 月 4 日和 5 日发生的事情的简要回顾。
尽管正式的开幕式要到周日晚上才会举行,但峰会前的活动还是很精彩的。亮点之一(特别是对于这里的体育爱好者而言)是早上的高尔夫锦标赛和足球(又名足球)比赛。不能说关于足球的任何事情,因为我不在场(如果你在场,请在评论部分发表评论和照片!),但据我所知,这是一场有趣的比赛。我可以告诉你关于高尔夫的事!
比赛从早上 6 点开始,一直持续到下午 2 点左右。一开始天气阴沉,雨刚下完。但几个小时后,太阳出现了,防晒霜也随之出现。让我告诉你,50SPF 感觉不够!
为了让它更有趣,当地的动物群决定也出去玩。
在宣布获奖者并享用午餐后,我们返回 The Diplomat Beach Hotel 参加其他活动。
例如,下午有一场女性活动。
这导致周日的主要活动 - 欢迎酒会!这是看到熟悉的面孔并与同事和朋友取得联系的最佳时机。
例如,英语社区的版主(@Muhammad.Waseem、@Dmitry.Maslennikov、@Irène.Mykhailova):
和法语社区(@Lorenzo.Scalese、@Irène.Mykhailova、@Dmitry.Maslennikov、@Guillaume.Rongier7183):
这是“准备”日。主要内容从周一开始!
Terry Ragon 开启了峰会,在他的演讲中提醒大家任何成功的公司都必须创新才能保持相关性。 InterSystems 就是这样的公司之一!
此外,他祝贺大家 InterSystems 成立 45 周年和第 30 届全球峰会!这不是令人兴奋吗?不知道你怎么想,公司成立的时候我还没有出生呢!
开场白之后,第一个主题演讲是关于医疗保健的。其中一点 @Donald.Woodlock 谈到了AI 以及它如何拉近开发人员与客户的距离,而不是相反。
在主题演讲(和午餐)之后,每个人都分散到不同的会议、演讲、会议等。我回到了 Tech Exchange 的开发者社区展位。
如果你在峰会上,别忘了顺路过来——我很乐意给你一些礼物作为简单行动的回报 😘 如果你认识一些还不是社区成员的人,鼓励他们过来也得到一些赃物。此外,请查看全球大师赛- 峰会期间可兑换一些奖励:
还有一些新的(和旧的最爱)奖励!有传言说,我们甚至很快就会有笔记本电脑贴纸!
无论如何,在 DevCom 展位让我有机会与新朋友交谈,并结识其他有空的版主。
@Guillaume.Rongier7183 和@Dmitry.Maslennikov
@Lorenzo.Scalese、@Dmitry.Maslennikov 和@Francisco.López1549
如果您对背景中的演示文稿感兴趣,请看这里。
此外,参加 Tech Exchange 意味着我可以关注那里正在进行的所有演示。例如,了解容器 😉
在所有这些兴奋之后,我们都去吃晚餐和演示。
玩游戏,玩得很开心。
这是 2023 年全球峰会的第一个官方日。敬请期待接下来的活动!
文章
姚 鑫 · 四月 24, 2021
# 第五章 优化查询性能(三)
# 查询执行计划
可以使用解释或显示计划工具来显示`SELECT`、`DECLARE`、`UPDATE`、`DELETE`、`TRUNCATE TABLE`和一些`INSERT`操作的执行计划。这些操作统称为查询操作,因为它们使用`SELECT`查询作为其执行的一部分。InterSystems IRIS在准备查询操作时生成执行计划;不必实际执行查询来生成执行计划。
默认情况下,这些工具显示InterSystems IRIS认为的最佳查询计划。对于大多数查询,有多个可能的查询计划。除了InterSystems IRIS认为最佳的查询计划外,还可以生成和显示备用查询执行计划。
InterSystems IRIS提供以下查询计划工具:
- `$SYSTEM.SQL.ExPlan()`方法可用于生成和显示`XML`格式的查询计划以及备选查询计划(可选)。
- SQL `EXPLAIN`命令可用于生成`XML`格式的查询计划,还可以选择生成备选查询计划和SQL统计信息。所有生成的查询计划和统计信息都包含在名为Plan的单个结果集字段中。请注意,`EXPLAIN`命令只能与`SELECT`查询一起使用。
- 管理门户 - >系统资源管理器 - >SQL界面显示计划按钮。
- 管理门户 — >系统资源管理器 — >工具—>SQL性能工具。

对于生成的`%PARALLEL`和分片查询,这些工具显示所有适用的查询计划。
## 使用`Explain()`方法
可以通过运行`$SYSTEM.SQL.Explain()`方法生成查询执行计划,示例如下:
```java
/// w ##class(PHA.TEST.SQL).SQLExplain()
ClassMethod SQLExplain()
{
SET mysql=2
SET mysql(1)="SELECT TOP 10 Name,DOB FROM Sample.Person "
SET mysql(2)="WHERE Name [ 'A' ORDER BY Age"
SET status=$SYSTEM.SQL.Explain(.mysql,{"all":0,"quiet":1,"stats":0,"preparse":0},,.plan)
IF status'=1 {WRITE "Explain() failed:" DO $System.Status.DisplayError(status) QUIT}
ZWRITE plan
}
```
设置`“all”:0`选项会生成InterSystems IRIS认为最优的查询计划。
设置`“all”:1`选项会生成最佳的查询计划和备选的查询计划。
默认值为`“all”:0`。
结果被格式化为表示`xml`格式文本的下标数组。
如果指定单个查询计划`("all":0)`,上述方法调用中的plan变量将具有以下格式:
- `plan`:显示结果中的下标总数。
- `plan(1)`:总是包含XML格式标签`“”`。
最后一个下标总是包含XML格式标记`“”`。
- `plan(2)`:总是包含XML格式标签`""`
- `plan(3)`: 总是包含查询文本的第一行。
如果"`"preparse":0`(默认值),则返回字面查询文本,并为多行查询的每一行使用额外的下标;在上面的例子中,查询有两行,因此使用了两个下标`(plan(3)`和`plan(4)`)。如果`"prepare":1`,则规范化查询文本返回为单行`:plan(3)`。
- `plan(n)`:总是包含XML格式标签`“”`;
在上面的例子中,`3+mysql = plan(5)`。
- `plan(n+1)`:总是包含XML格式的查询`cost""`.
- `plan(n+2)`:总是包含执行计划的第一行。
这个plan可以是任何长度,可以包含`…`标签作为单独的下标行,包含生成的执行模块的查询计划。
如果指`"all":1 Explain()`将生成备用查询计划。计划变量遵循相同的格式,不同之处在于它们使用第一级下标来标识查询计划,而使用第二级下标来标识查询计划的行。因此,`plan(1)`包含第一个查询计划结果中的二级下标计数,`plan(2)`包含第二个查询计划结果中的二级下标计数,依此类推。在此格式中,`plan(1,1)`包含第一个查询计划的`XML`格式标记 `""`;`plan(2,1)`包含第二个查询计划的XML格式标记 `""`,依此类推。唯一不同的是,备用查询计划包含二级零下标(`plan(1,0)`变量,该变量包含成本和索引信息;此零下标不计入一级下标(`plan(1)`)值。
如果指`"stats":1`, `Explain()`将为每个查询计划模块生成性能统计信息。
每个模块的这些统计数据都使用` ... `标记,并立即出现在查询成本之后(`""`)和查询计划文本之前。
如果查询计划包含额外的``标记,则生成的模块的``将紧接在``标记之后,在该模块的查询计划之前列出。
对于每个模块,将返回以下项:
- ``:模块名。
- ``:模块的总执行时间,以秒为单位。
- ``:全局引用的计数。
- ``:执行的代码行数。
- ``:磁盘等待时间,单位为秒。
- ``:结果集中的行数。
- ``:此模块被执行的次数。
- ``:这个程序被执行的次数。
## 使用显示计划从InterSystems SQL工具
可以使用`Show Plan`以以下任何一种方式显示查询的执行计划
- 从管理门户SQL接口。
选择`System Explorer`,然后选择SQL。
在页面顶部选择带有`Switch`选项的名称空间。
(可以为每个用户设置管理门户的默认名称空间。)
编写查询,然后按`Show Plan`按钮。
(还可以通过单击列出查询的`Plan`选项,从`Show History`列表调用`Show Plan`。)
- 从管理门户工具界面。
选择“系统资源管理器”,然后选择“工具”,然后选择“SQL性能工具”,然后选择“SQL运行时统计信息”:
- 在`Query Test`选项卡中:在页面顶部选择一个带有`Switch`选项的名称空间。
在文本框中写入查询。
然后按下`Show Plan with SQL Stats`按钮。
这将在不执行查询的情况下生成一个显示计划。
- 在`View Stats`选项卡中:对于列出的查询之一,按`Show Plan`按钮。
列出的查询包括在执行查询时编写的查询和在查询测试时编写的查询。
- 在`SQL Shell`中,可以使用`SHOW PLAN`和`SHOW PLANALT Shell`命令来显示最近执行的查询的执行计划。
- 通过对缓存的查询结果集运行`Show Plan`,使用:`i%Prop`语法将文本替换值存储为属性:
```java
SET cqsql=2
SET cqsql(1)="SELECT TOP :i%PropTopNum Name,DOB FROM Sample.Person "
SET cqsql(2)="WHERE Name [ :i%PropPersonName ORDER BY Age"
DO ShowPlan^%apiSQL(.cqsql,0,"",0,$LB("Sample"),"",1)
```
默认情况下,`Show Plan`以逻辑模式返回值。但是,当从管理门户或SQL Shell调用`Show Plan`时,`Show Plan`使用运行时模式。
## 执行计划:语句文本和查询计划
显示计划执行计划由两个组件组成,即语句文本和查询计划:
语句文本复制了原始查询,但进行了以下修改:管理门户SQL界面中的显示计划按钮显示删除了注释和换行符的SQL语句。空格是标准化的。显示计划按钮显示还执行文字替换,将每个文字替换为`?`,除非已通过将文字值括在双圆括号中来取消文字替换。使用`EXPLAIN()`方法显示显示计划时,或者使用SQL运行时统计信息或备用显示计划工具显示显示计划时,不会执行这些修改。
查询计划显示将用于执行查询的计划。查询计划可以包括以下内容:
- 如果查询计划已经冻结,则查询计划的第一行为冻结计划,否则第一行为空。
- `“Relative cost”`是一个整数值,它是从许多因素中计算出来的抽象数字,用于比较同一查询的不同执行计划的效率。
这种计算考虑了查询的复杂性、索引的存在和表的大小(以及其他因素)。
相对成本对于比较两个不同的查询是没有用的。
`" Relative cost not available"`由某些聚合查询返回,例如`COUNT(*)`或`MAX(%ID)`不带`WHERE`子句。
- 查询计划由一个主模块和(在需要时)一个或多个子组件组成。
可以显示一个或多个模块子组件,按字母顺序命名, `B: Module:B`, `Module:C`,等等开始,并按执行顺序列出(不一定按字母顺序)。
默认情况下,模块执行处理并使用其结果填充内部临时文件(内部临时表)。
通过指定 `/*#OPTIONS {"NoTempFile":1} */`,可以强制查询优化器创建不生成内部临时文件的查询计划,如注释选项中所述。
对于查询中的每个子查询,都会显示一个命名子查询模块。子查询模块按字母顺序命名。子查询命名在每个命名子查询之前跳过一个或多个字母。因此 `Module:B`, `Subquery:F or Module:D`, `Subquery:G`.当到达字母表末尾时,会对其他子查询进行编号,解析`Z=26`并使用相同的跳过序列。下面的示例是以`Subquery`开头的每三个子查询命名序列`:F:F,I,L,O,R,U,X,27,30,33`。下面的示例是以`Subquery`开头的每秒一次的子查询命名序列`:G:G,I,K,M,O,Q,S,U,W,Y,27,29`。如果子查询调用模块,模块将按字母顺序放在子查询之后,不会跳过。因此,`Subquery:H calls Module:I`。
- `“Read master map”`作为主模块中的第一个项目符号表示查询计划效率低下。查询计划使用以下映射类型语句之一开始执行`Read master map... (no available index), Read index map... (use available index), or Generate a stream of idkey values using the multi-index combination...`因为`master map`读取的是数据本身,而不是数据的索引,所以`Read master map...`。几乎总是指示低效的查询计划。除非表相对较小,否则应该定义一个索引,以便在重新生成查询计划时,第一个映射显示为`read index map...`。
某些操作会创建表示无法生成查询计划的显示计划:
- 非查询插入:`INSERT... VALUES()`命令不执行查询,因此不生成查询计划。
- 查询总是`FALSE`:在少数情况下,InterSystems IRIS可以在准备查询时确定查询条件总是`FALSE`,因此不能返回数据。“显示计划”会在“查询计划”组件中通知这种情况。例如,包含条件的查询`WHERE %ID IS NULL 或 WHERE Name %STARTSWITH('A') AND Name IS NULL `不能返回数据,因此,InterSystems IRIS不生成执行计划。查询计划没有生成执行计划,而是表示`“Output no rows”`。如果查询包含具有这些条件之一的子查询,则查询计划的子查询模块表示`“Subquery result NULL, found no rows”`。这种条件检查仅限于涉及`NULL`的几种情况,并不是为了捕捉所有自相矛盾的查询条件。
- 无效的查询:`Show Plan`为大多数无效查询显示`SQLCODE错误消息`。然而,在少数情况下,`Show Plan`显示为空。例如, `WHERE Name = $$$$$ or WHERE Name %STARTSWITH('A")`。在这些情况下,`Show Plan`不显示语句文本,而`Query Plan[没有为该语句创建的计划]`。这通常发生在分隔文字的引号不平衡时。
当为用户定义的(“外部”)函数指定了两个或多个前置美元符号而没有指定正确的语法时,也会出现这种情况。
# 交替显示计划
可以使用管理门户或`Explain()`方法显示查询的替代执行计划。
使用以下任意一种方法,从管理门户显示查询的备选执行计划:
- 选择系统资源管理器,选择工具,选择SQL性能工具,然后选择备用的显示计划。
- 选择`System Explorer`,选择SQL,然后从Tools下拉菜单中选择`Alternate Show Plans`。


使用备用的“显示计划”工具:
1. 输入一个SQL查询文本,或使用`Show History`按钮检索一个。
可以通过单击右边的圆形“X”圆来清除查询文本字段。
2. 按显示计划选项按钮以显示多个备用显示计划。 `Run ... in the background...`默认情况下不选中复选框,这是大多数查询的首选设置。建议选择`RUN...`。对于大型或复杂的查询,请在后台复选框中。当一个长查询在后台运行时,会显示一个`View process`按钮。单击查看进程将在新选项卡中打开进程详细信息页面。在“进程详细信息”页中,可以查看进程,还可以挂起、继续或终止进程。
3. 可能的计划按成本升序列出,并带有映射类型和起始映射。
4. 从可能的计划列表中,使用复选框选择要比较的计划,然后按比较显示计划与统计信息按钮以运行这些计划并显示其SQL统计信息。
带有`ALL`限定符的`EXPLAIN()`方法显示查询的所有执行计划。它首先显示IRIS认为最优(成本最低)的计划,然后显示备选计划。备选计划按成本升序列出。
以下示例显示最佳执行计划,然后列出备选计划:
```java
DO $SYSTEM.SQL.SetSQLStatsFlagJob(3)
SET mysql=1
SET mysql(1)="SELECT TOP 4 Name,DOB FROM Sample.Person ORDER BY Age"
DO $SYSTEM.SQL.Explain(.mysql,{"all":1},,.plan)
ZWRITE plan
```
## Stats
显示计划选项列表为每个备用显示计划分配一个成本值,使可以在执行计划之间进行相对比较。
`Alternate Show Plan Details`为每个查询计划提供了一组查询总数的统计信息(统计信息),以及(如果适用)每个查询计划模块的统计信息。每个模块的统计信息包括时间(整体性能,以秒为单位)、全局引用(全局引用数)、命令(执行的行数)和读取延迟(磁盘等待,以毫秒为单位)。查询总计统计信息还包括返回的行数。
# 将查询优化计划写入文件
以下实用程序列出了针对文本文件的一个或多个查询的查询优化计划。
```java
QOPlanner^%apiSQL(infile,outfile,eos,schemapath)
```
- `infile` 包含缓存查询列表的文本文件的文件路径名。指定为带引号的字符串。
- `outfile` 要列出查询优化计划的文件路径名。指定为带引号的字符串。如果该文件不存在,系统将创建该文件。如果该文件已存在,则InterSystems IRIS会覆盖该文件。
- `eos` 可选-语句末尾分隔符,用于分隔`Infile`列表中的各个缓存查询。指定为带引号的字符串。默认值为`“GO”`。如果此`EOS`字符串与缓存的查询分隔符不匹配,则不会生成输出文件。
- `schemapath` 可选-以逗号分隔的方案名列表,用于为未限定的表名、视图名或存储过程名指定方案搜索路径。可以包括`DEFAULT_SCHEMA`,这是当前系统范围内的默认架构。如果`infile`包含`#Import`指令,`QOPlanner`会将这些`#Import`包/架构名称添加到`schemapath`的末尾。
以下是调用此查询优化计划列表实用程序的示例。该实用程序将`ExportSQL^%qarDDLExport()`实用程序生成的文件作为输入,如“缓存查询”一章的“将缓存查询列出到文件”一节中所述。可以生成此查询列表文件,也可以将一个(或多个)查询写入文本文件。
```java
DO QOPlanner^%apiSQL("C:\temp\test\qcache.txt","C:\temp\test\qoplans.txt","GO")
```
从终端命令行执行时,进度会显示在终端屏幕上,如下例所示:
```java
Importing SQL Statements from file: C:\temp\test\qcache.txt
Recording any errors to principal device and log file: C:\temp\test\qoplans.txt
SQL statement to process (number 1):
SELECT TOP ? P . Name , E . Name FROM Sample . Person AS P ,
Sample . Employee AS E ORDER BY E . Name
Generating query plan...Done
SQL statement to process (number 2):
SELECT TOP ? P . Name , E . Name FROM %INORDER Sample . Person AS P
NATURAL LEFT OUTER JOIN Sample . Employee AS E ORDER BY E . Name
Generating query plan...Done
Elapsed time: .16532 seconds
```
创建的查询优化计划文件包含如下条目:
```java
SELECT TOP ? P . Name , E . Name FROM Sample . Person AS P , Sample . Employee AS E ORDER BY E . Name
Read index map Sample.Employee.NameIDX.
Read index map Sample.Person.NameIDX.
######
SELECT TOP ? P . Name , E . Name FROM %INORDER Sample . Person AS P
NATURAL LEFT OUTER JOIN Sample . Employee AS E ORDER BY E . Name
Read master map Sample.Person.IDKEY.
Read extent bitmap Sample.Employee.$Employee.
Read master map Sample.Employee.IDKEY.
Update the temp-file.
Read the temp-file.
Read master map Sample.Employee.IDKEY.
Update the temp-file.
Read the temp-file.
######
```
可以使用查询优化计划文本文件来比较使用不同查询变体生成的优化计划,或者比较不同版本的InterSystems IRIS之间的优化计划。
将SQL查询导出到文本文件时,来自类方法或类查询的查询将以代码行开头:
```java
#import
```
这个`#Import`语句告诉`QOPlanner`实用程序使用哪个默认包/模式来生成查询计划。从例程导出SQL查询时,例程代码中SQL语句之前的任何`#import`行也将位于导出文件中的SQL文本之前。假设从缓存查询导出到文本文件的查询包含完全限定的表引用;如果文本文件中的表引用不是完全限定的,则`QOPlanner`实用程序使用在运行`QOPlanner`时在系统上定义的系统范围的默认模式。
文章
姚 鑫 · 四月 6, 2021
# 第十八章 定义和使用存储过程
本章介绍如何在IntersystemsIRIS®数据平台上定义和使用Intersystems SQL中的存储过程。它讨论了以下内容:
- 存储过程类型的概述
- 如何定义存储过程
- 如何使用存储过程如
- 何列出存储过程及其参数。
# 概述
SQL例程是可执行的代码单元,可以由SQL查询处理器调用。 SQL例程有两种类型:功能和存储过程。从支持`FunctionName()`语法的任何SQL语句中调用函数。存储过程只能由`CALL`语句调用。函数接受某些输入定向参数并返回单个结果值。存储过程接受某些输入,输入输出和输出参数。存储过程可以是用户定义的函数,返回单个值。 `CALL`语句也可以调用函数。
与大多数关系数据库系统一样,Intersystems Iris允许创建SQL存储过程。存储过程(SP)提供存储在数据库中的可调用可调用的程序,并且可以在SQL上下文中调用(例如,通过使用呼叫语句或通过ODBC或JDBC)。
与关系数据库不同,Intersystems Iris使可以将存储过程定义为类的方法。实际上,存储过程只不过是SQL可用的类方法。在存储过程中,可以使用基于对象的全系列Intersystems的功能。
- 可以通过查询数据库将存储过程定义为返回单个结果集数据集的查询。
- 可以将存储过程定义为可以用作用户定义函数的函数过程,返回单个值。
- 可以将存储过程定义为可以修改数据库数据并返回单个值或一个或多个结果集的方法。
可以确定使用 `$SYSTEM.SQL.Schema.ProcedureExists()`方法是否已存在该过程。此方法还返回过程类型:`“函数function”`或`“查询query”`。
# 定义存储过程
与Intersystems SQL的大多数方面一样,有两种方法可以定义存储过程:使用DDL和使用类。这些在以下部分中描述。
## 使用DDL定义存储过程
Intersystems SQL支持以下命令来创建查询:
- `CREATE PROCEDURE`可以创建始终作为存储过程投影的查询。
查询可以返回单个结果集。
- `CREATE QUERY`创建一个查询,该查询可以选择性地投影为存储过程。
查询可以返回单个结果集。
InterSystems SQL支持以下命令来创建方法或函数:
- `CREATE PROCEDURE`可以创建始终作为存储过程投影的方法。
方法可以返回单个值,也可以返回一个或多个结果集。
- `CREATE METHOD`可以创建一个方法,该方法可以选择投影为存储过程。
方法可以返回单个值,也可以返回一个或多个结果集。
- `CREATE FUNCTION`可以创建一个函数过程,该函数过程可以选择投影为存储过程。
函数可以返回单个值。
这些命令中指定的可执行代码块可以用InterSystems SQL或ObjectScript编写。
可以在ObjectScript代码块中包含嵌入式SQL。
## SQL到类名转换
使用DDL创建存储过程时,指定的名称将转换为类名。
如果类不存在,系统将创建它。
- 如果名称是不限定的,并且没有提供FOR子句:使用系统范围的默认模式名作为包名,后跟一个点,后跟一个生成的类名,由字符串 `‘func’`, `‘meth’`, `‘proc’`, or `‘query’`组成,后跟去掉标点字符的SQL名。
例如,未限定的过程名`Store_Name`会产生如下类名`User.procStoreName`:
这个过程类包含方法`StoreName()`。
- 如果名称是限定的,并且没有提供`FOR`子句:模式名被转换为包名,后跟一个点,后跟字符串`‘func’`, `‘meth’`,` ‘proc’`, or `‘query’` ,后跟去掉标点字符的SQL名。
如果需要,将指定的包名转换为有效的包名。
如果名称是限定的,并且提供了`FOR`子句:在`FOR`子句中指定的限定类名将覆盖在函数、方法、过程或查询名称中指定的模式名。
- SQL存储过程名称遵循标识符命名约定。
InterSystems IRIS从SQL名称中去除标点字符,从而为过程类及其类方法生成唯一的类实体名称。
下面的规则管理模式名到有效包名的转换:
- 如果架构名称包含下划线,则此字符将转换为点,表示子包。例如,合格的名称`myprocs.myname`创建包`myprocs`。限定名称`my_procs.myname`创建了包含子包`procs`的包。
以下示例显示了标点符号在类名和SQL调用中的不同之处。它定义了一个包含包含两个点的类名的方法。从SQL中调用时,示例将第一个点替换为下划线字符:
```java
Class Sample.ProcTest Extends %RegisteredObject
{
ClassMethod myfunc(dummy As %String) As %String [ SqlProc ]
{
/* method code */
Quit "abc"
}
}
```
```java
SELECT Sample.ProcTest_myfunc(Name)
FROM Sample.Person
```
## 使用类定义方法存储过程
类方法可以公开为存储过程。
这些是不返回数据的操作的理想选择,例如计算值并将其存储在数据库中的存储过程。
几乎所有类都可以将方法公开为存储过程;
例外是生成器类,比如数据类型类(`[ClassType = datatype]`)。
生成器类没有运行时上下文。
只有在其他实体(如属性)的运行时中使用数据类型上下文才有效。
**要定义方法存储过程,只需定义一个类方法并设置其`SqlProc`关键字:**
```java
Class MyApp.Person Extends %Persistent [DdlAllowed]
{
/// This procedure finds total sales for a territory
ClassMethod FindTotal(territory As %String) As %Integer [SqlProc]
{
// use embedded sql to find total sales
&sql(SELECT SUM(SalesAmount) INTO :total
FROM Sales
WHERE Territory = :territory
)
Quit total
}
}
```
编译这个类之后,`FindTotal()`方法将作为存储过程`MyApp.Person_FindTotal()`投影到SQL中。
可以使用方法的`SqlName`关键字更改SQL对过程使用的名称。
该方法使用过程上下文处理程序在过程及其调用者(例如,ODBC服务器)之间来回传递过程上下文。
这个过程上下文处理程序是由InterSystems IRIS(作为`%qHandle:%SQLProcContext`)使用%`sqlcontext`对象自动生成的。
`%sqlcontext`由`SQLCODE`错误状态、SQL行数、错误消息等属性组成,使用相应的SQL变量设置,如下所示:
```java
SET %sqlcontext.%SQLCode=SQLCODE
SET %sqlcontext.%ROWCOUNT=%ROWCOUNT
SET %sqlcontext.%Message=%msg
```
不需要对这些值做任何事情,但是它们的值将由客户机解释。
在每次执行之前都会重置`%sqlcontext`对象。
该方法不应该返回任何值。
一个类的用户定义方法的最大数目是`2000`个。
例如,假设有一个`CalcAvgScore()`方法:
```java
ClassMethod CalcAvgScore(firstname As %String,lastname As %String) [sqlproc]
{
New SQLCODE,%ROWID
&sql(UPDATE students SET avgscore =
(SELECT AVG(sc.score)
FROM scores sc, students st
WHERE sc.student_id=st.student_id
AND st.lastname=:lastname
AND st.firstname=:firstname)
WHERE students.lastname=:lastname
AND students.firstname=:firstname)
IF ($GET(%sqlcontext)'= "") {
SET %sqlcontext.%SQLCODE = SQLCODE
SET %sqlcontext.%ROWCOUNT = %ROWCOUNT
}
QUIT
}
```
## 使用类定义查询存储过程
许多从数据库返回数据的存储过程可以通过标准查询接口实现。
只要可以用嵌入式SQL编写过程,这种方法就可以很好地工作。
注意,在以下示例中,使用了嵌入式SQL `host`变量为`WHERE`子句提供一个值:
```java
Class MyApp.Person Extends %Persistent [DdlAllowed]
{
/// This procedure result set is the persons in a specified Home_State, ordered by Name
Query ListPersons(state As %String = "") As %SQLQuery [ SqlProc ]
{
SELECT ID,Name,Home_State
FROM Sample.Person
WHERE Home_State = :state
ORDER BY Name
}
}
```
要将查询公开为存储过程,可以将Studio Inspector条目中的`SQLProc`字段的值更改为`True`,或者在查询定义中添加以下`“[SQLProc]”`字符串:
```java
Query QueryName() As %SQLQuery( ... query definition ... )
[ SqlProc ]
```
编译这个类之后,`ListPersons`查询将作为存储过程`MyApp.Person_ListPersons`投影到SQL中。
可以使用查询的`SqlName`关键字更改SQL用于该过程的名称。
当`MyApp`。
从SQL调用`Person_ListPersons`,它将自动返回由查询的SQL语句定义的结果集。
下面是一个使用结果集的存储过程的示例:
```java
Class apc.OpiLLS.SpCollectResults1 [ Abstract ]
{
/// This SP returns a number of rows (pNumRecs) from WebService.LLSResults, and updates a property for each record
Query MyQuery(pNumRecs As %Integer) As %Query(ROWSPEC = "Name:%String,DOB:%Date") [ SqlProc ]
{
}
/// You put initial code here in the Execute method
ClassMethod MyQueryExecute(ByRef qHandle As %Binary, pNumRecs As %Integer) As %Status
{
SET mysql="SELECT TOP ? Name,DOB FROM Sample.Person"
SET rset=##class(%SQL.Statement).%ExecDirect(,mysql,pNumRecs)
IF rset.%SQLCODE'=0 {QUIT rset.%SQLCODE}
SET qHandle=rset
QUIT $$$OK
}
/// This code is called by the SQL framework for each row, until no more rows are returned
ClassMethod MyQueryFetch(ByRef qHandle As %Binary, ByRef Row As %List,
ByRef AtEnd As %Integer = 0) As %Status [ PlaceAfter = NewQuery1Execute ]
{
SET rset=qHandle
SET tSC=$$$OK
FOR {
///Get next row, quit if end of result set
IF 'rset.%Next() {
SET Row = "", AtEnd = 1
SET tSC=$$$OK
QUIT
}
SET name=rset.Name
SET dob=rset.DOB
SET Row = $LISTBUILD(name,dob)
QUIT
}
QUIT tSC
}
ClassMethod MyQueryClose(ByRef qHandle As %Binary) As %Status [ PlaceAfter = NewQuery1Execute ]
{
KILL qHandle //probably not necesary as killed by the SQL Call framework
QUIT $$$OK
}
}
```
如果可以将查询编写为一个简单的SQL语句并通过查询向导创建它,那么就不需要了解实现查询的底层方法。
在后台,对于每个查询,类编译器都会根据存储过程的名称生成方法,包括:
- `stored-procedure-nameExecute()`
- `stored-procedure-nameFetch()`
- `stored-procedure-nameFetchRows()`
- `stored-procedure-nameGetInfo()`
- `stored-procedure-nameClose()`
如果查询类型为`%SQLQuery`,则类编译器会自动将一些嵌入式SQL插入到生成的方法中。
`Execute()`为SQL声明并打开存储的游标。
`Fetch()`被反复调用,直到它返回一个空行`(SET row ="")`。
还可以选择让`Fetch()`返回一个`AtEnd=1`布尔标志,以表明当前获取构成最后一行,下一个获取预期返回空行。
然而,应该总是使用空行`(row ="")`作为测试,以确定结果集何时结束;
当设置`AtEnd=1`时,应该始终设置`Row=""`。
`FetchRows()`在逻辑上等同于反复调用`Fetch()`。
调用`GetInfo()`返回存储过程签名的详细信息。
`Close()`关闭游标。
当从客户机调用存储过程时,会自动调用所有这些方法,但理论上可以从运行在服务器上的ObjectScript直接调用这些方法。
要将对象从`Execute()`传递给`Fetch()`,或从`Fetch()`传递给下一次调用`Fetch()`,可以将查询处理程序设置为希望传递的对象的对象引用(`oref`)。
要传递多个对象,可以将`qHandle`设置为一个数组:
```java
SET qHandle(1)=oref1,qHandle(2)=oref2
```
可以基于自定义编写的代码(而不是SQL语句)创建结果集存储过程。
对一个类的用户定义查询`Query`的最大数目是200。
## 自定义Query
对于复杂的查询或不适合查询模型的存储过程,通常需要通过替换查询的部分或全部方法来自定义查询。
你可以使用 `%Library.Query`。
如果选择类型`%query` (`%Library.Query`)而不是`%SQLQuery` (`%Library.SQLQuery`),则通常更容易实现查询。
这生成了相同的5个方法,但是现在`FetchRows()`只是重复调用`Fetch()` (`%SQLQuery`进行了一些优化,导致了其他行为)。
`GetInfo()`只是从签名中获取信息,因此代码不太可能需要更改。
这将问题简化为为其他三个类中的每一个创建类方法。
请注意,在编译类时,编译器会检测到这些方法的存在,而不会覆盖它们。
**这些方法需要特定的签名:它们都接受类型为`%Binary`的`Qhandle`(查询处理程序)。
这是一个指向保存查询的性质和状态的结构的指针。
它通过引用传递给`Execute()`和`Fetch()`,通过值传递给`Close()`:**
```java
ClassMethod SP1Close(qHandle As %Binary) As %Status
{
// ...
}
ClassMethod SP1Execute(ByRef qHandle As %Binary,
p1 As %String) As %Status
{
// ...
}
ClassMethod SP1Fetch(ByRef qHandle As %Binary,
ByRef Row As %List, ByRef AtEnd As %Integer=0) As %Status
{
// ...
}
Query SP1(p1 As %String)
As %Query(CONTAINID=0,ROWSPEC="lastname:%String") [sqlproc ]
{
}
```
代码通常包括SQL游标的声明和使用。
从类型为`%SQLQuery`的查询中生成的游标自动具有诸如`Q14`这样的名称。
必须确保查询具有不同的名称。
在尝试使用游标之前,类编译器必须找到游标声明。
因此,`DECLARE`语句(通常在`Execute`中)必须与`Close`和`Fetch`语句在同一个MAC例程中,并且必须出现在它们中的任何一个之前。
直接编辑源代码,**在`Close`和`Fetch`定义中都使用方法关键字`PLACEAFTER`,以确保实现这一点。**
错误消息引用内部游标名,它通常有一个额外的数字。
因此,游标`Q140`的错误消息可能指向`Q14`
# 使用存储过程
使用存储过程有两种不同的方式:
- 可以使用SQL `CALL`语句调用存储过程;
- 可以像使用SQL查询中的内置函数一样使用存储函数(即返回单个值的基于方法的存储过程)。
-
注意:当执行一个以SQL函数为参数的存储过程时,请使用`CALL`调用存储过程,示例如下:
```
CALL sp.MyProc(CURRENT_DATE)
```
**`SELECT`查询不支持执行带有SQL函数参数的存储过程。
`SELECT`支持执行带有SQL函数参数的存储函数。**
`xDBC`不支持使用`SELECT`或`CALL`来执行带有SQL函数参数的存储过程。
## 存储方法
存储函数是返回单个值的基于方法的存储过程。
例如,下面的类定义了一个存储函数`Square`,它返回给定值的平方:
```java
Class MyApp.Utils Extends %Persistent [DdlAllowed]
{
ClassMethod Square(val As %Integer) As %Integer [SqlProc]
{
Quit val * val
}
}
```
存储的函数只是指定了`SqlProc`关键字的类方法。
注意:对于存储的函数,`ReturnResultsets`关键字必须不指定(默认)或以关键字`not`作为开头。
可以在SQL查询中使用存储函数,就像使用内置SQL函数一样。
函数的名称是存储函数(在本例中为`“Square”`)的SQL名称,该名称由定义该函数的模式(包)名称限定(在本例中为`“MyApp”`)。
下面的查询使用了`Square`函数:
```sql
SELECT Cost, MyApp.Utils_Square(Cost) As SquareCost FROM Products
```
如果在同一个包(模式)中定义了多个存储函数,则必须确保它们具有惟一的SQL名称。
下面的示例定义了一个名为`Sample`的表。
具有两个定义的数据字段(属性)和两个定义的存储函数`TimePlus`和`DTime`的工资:
```java
Class Sample.Wages Extends %Persistent [ DdlAllowed ]
{
Property Name As %String(MAXLEN = 50) [ Required ];
Property Salary As %Integer;
ClassMethod TimePlus(val As %Integer) As %Integer [ SqlProc ]
{
QUIT val * 1.5
}
ClassMethod DTime(val As %Integer) As %Integer [ SqlProc ]
{
QUIT val * 2
}
}
```
下面的查询使用这些存储过程返回同一个表`Sample.Wages`中每个员工的`Salary`、`time- half`和`double time`工资率:
```java
SELECT Name,Salary,
Sample.Wages_TimePlus(Salary) AS Overtime,
Sample.Wages_DTime(Salary) AS DoubleTime FROM Sample.Wages
```
下面的查询使用这些存储过程返回不同表`Sample.Employee`中每个员工的`Salary`、`time- half`和`double time`工资率:
```
SELECT Name,Salary,
Sample.Wages_TimePlus(Salary) AS Overtime,
Sample.Wages_DTime(Salary) AS DoubleTime FROM Sample.Employee
```
## 权限
要执行一个过程,用户必须具有该过程的`execute`权限。
使用`GRANT`命令或`$SYSTEM.SQL.Security.GrantPrivilege()`方法将指定过程的执行权限分配给指定用户。
通过调用`$SYSTEM.SQL.Security.CheckPrivilege()`方法,可以确定指定的用户是否具有指定过程的执行权限。
要列出用户具有`EXECUTE`权限的所有过程,请转到管理门户。
从系统管理中选择Security,然后选择Users或Roles。
为所需的用户或角色选择Edit,然后选择SQL Procedures选项卡。
从下拉列表中选择所需的名称空间。
# List 存储过程
`INFORMATION.SCHEMA.ROUTINES persistent`类显示关于当前命名空间中所有例程和过程的信息。
当在嵌入式SQL中指定时,`INFORMATION.SCHEMA`。
例程需要`#include %occInclude`宏预处理指令。
动态SQL不需要这个指令。
下面的例子返回例程名称、方法或查询名称、例程类型(过程或函数)、例程主体(`SQL=class query with SQL, EXTERNAL=not a class query with SQL`)、返回数据类型,以及当前命名空间中模式`“Sample”`中所有例程的例程定义:
```sql
SELECT ROUTINE_NAME,METHOD_OR_QUERY_NAME,ROUTINE_TYPE,ROUTINE_BODY,SQL_DATA_ACCESS,IS_USER_DEFINED_CAST,
DATA_TYPE||' '||CHARACTER_MAXIMUM_LENGTH AS Returns,NUMERIC_PRECISION||':'||NUMERIC_SCALE AS PrecisionScale,
ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='SQLUser'
```

`INFORMATION.SCHEMA.PARAMETERS persistent`类显示关于当前命名空间中所有例程和过程的输入和输出参数的信息。
下面的示例返回例程名称、参数名称(不管是输入参数还是输出参数)以及当前命名空间中模式`“Sample”`中的所有例程的参数数据类型信息:
```
SELECT SPECIFIC_NAME,PARAMETER_NAME,PARAMETER_MODE,ORDINAL_POSITION,
DATA_TYPE,CHARACTER_MAXIMUM_LENGTH AS MaxLen,NUMERIC_PRECISION||':'||NUMERIC_SCALE AS PrecisionScale
FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA='SQLUser'
```

使用管理门户SQL界面中的Catalog Details选项卡,可以为单个过程显示大部分相同的信息。
过程的目录详细信息包括过程类型(查询或函数)、类名称、方法或查询名称、描述以及输入和输出参数的数量。
目录详细信息存储过程信息显示还提供了运行存储过程的选项。
公告
Johnny Wang · 十二月 23, 2021
12月25日-26日,首届全国医疗健康信息互联互通与智慧医院建设大会即将拉开帷幕!本次会议以“互联互通——通向智慧医院的桥梁”为主题,将采用线上形式召开。
会议分为两大部分(点击“阅读原文”查看全部日程及报名方式)
#12月25日#
开幕式及综合论坛
12月25日,会议包含丰富的主题演讲,以及如下首发与启动仪式:
1. 中文医学术语(含中医)系统:首发面向联盟医疗机构提供中文医学术语(含中医)标准集和知识图谱等系统资源的访问服务,推进术语标准落地和发展,为我国智慧医院建设提供可持续的信息化支撑。
2. 2021年度医疗健康信息化企业影响力榜单:榜单聚焦医疗健康信息化企业,围绕医疗健康信息化软件产品,从企业的市场规模、企业形象、产品服务、技术创新等多个维度,全方位展示企业综合影响力,宣传推广优秀企业品牌,促进医疗信息化市场良性竞争,更好地为医院高质量发展提供信息化服务。
3. 启动“互联互通促进智慧医院建设”征文活动:总结近年来医院信息互联互通建设成效,梳理医院高质量发展路径,探讨医疗健康信息互联互通在促进电子病历、智慧服务、智慧管理“三位一体”智慧医院建设中的作用和成效。
4. 启动全国医疗健康首席数据官能力提升项目:以数据赋能与创新驱动为理念,融合多元知识和技能体系,通过课堂授课、沙龙研讨、案例分析、实地考察等立体化培训形式,提升医疗健康首席数据官实施数据战略、建设数据资源、保障数据安全、管理数据资产、创造数据价值的能力。
#12月26日#
六大平行论坛
12月26日上午
专题论坛——以质量为根本的智慧临床
医院电子病历建设与应用、医院集成平台建设与发展、新一代医院数据中心建设、医学人工智能与临床决策支持;
专题论坛——以需求为导向的智慧服务
医院智慧服务与便民惠民、互联网医院建设与发展/互联网+医疗健康建设与发展、远程医疗建设与应用;
专题论坛——以精细为特征的智慧管理
医院智慧运营管理、物联网创新应用与智慧后勤、公立医院绩效考核;
12月26日下午
专题论坛——以价值为核心的数据治理
医院数据治理建设与应用、大数据平台与数据建模、临床科研信息化建设、医疗健康数据利用与挖掘;
专题论坛——以主动为方向的网络安全
医院信息安全规划与建设、互联网+医疗健康安全建设、医院数据安全建设与管理;
专题论坛——以标准为基础的测评培训
医院信息互联互通测评方案解读、迎评促建筹备注意事项、互联互通测评经验分享与创新实践。InterSystems将在此分论坛中进行技术分享。
#InterSystems 技术分享#
从软件和集成架构的发展看互联互通
演讲人:乔鹏
InterSystems中国技术总监
乔鹏对于数据库、医疗相关标准以及集成平台解决方案,有着深刻的理解和十多年的行业经验,参与主导过百余家医院或者区域平台的信息化建设,同时对CDR、临床决策支持、商业智能、机器学习等数据利用产品和方案有深刻的洞察和丰富的实践经验。
演讲主题:从软件和集成架构的发展看互联互通
目前互联互通的实现架构类型不少,这些架构各自有哪些优点和缺点?是否满足不断发展的互联互通需求?医院在考虑这些架构时要注意哪些事项?有没有最佳实践?此次技术分享将从软件和集成架构的发展历史和趋势分析互联互通,并尝试回答这些问题。
专题论坛“以标准为基础的测评培训”
详细日程
阅读原文(查看大会详细日程 | 报名参会)
文章
yaoguai wan · 九月 30, 2022
前言
本人因技术需要,了解到了IRIS Health产品,在听了产品介绍会之后,感觉该产品是否有趣,并且比较符合自己目前的需求,因此大概了解了下IRIS的架构。以下是本人的浅显理解,如有错误之处欢迎讨论。
本人从产品介绍和社区的文档中,了解到IRIS的大概功能分类
InterSystems IRIS是一款数据平台,适用于软甲开发人员
基于FHIR
整合医疗全流程数据,通过机器学习和人工智能分析
业务优化
数据管理
Sharding数据分片技术
分布式架构
IRIS互操作性
数据分析能力
IRIS对FHIR的支持
机器学习与自动化
其中结合到自己想要研究的领域,想要探索是否可以利用该产品并结合其他工具开发一套通用的专病数据库构建及应用方法。
我目前对该产品的初步定位是对自行提供的数据集合的存储和处理,其中提供包括编码规范、高效存储架构、编程接口、算法在内的辅助工具。针对数据的处理和应用,该产品做的很完善,但是对于数据的获取,例如是否支持extract-transformation-load功能,或者能否利用自定义编程接口实现流批一体化数据抽取。根据上述两个问题,第一步需要安装该产品,所以本人根据社区官网上相关的安装教程进行了安装实验,在此期间发现了社区的教程有些简单并且有些关键点很容易被忽视本人在安装过程中就遇到过一个和系联的工程师讨论了一段时间之后才发现的,因此想与大家分享下安装过程中遇到的一些问题,避免一些问题后,安装过程还是很简单的,傻瓜式操作,后面可以分享下我的安装命令。
问题分享
首先注意产品的平台基本要求,这是平台操作手册上讲的,一定要严格遵守否则会报各种奇怪的错误,IRIS对不同版本的操作系统间的兼容性还有比较严格的,要注意,操作系统和后面容器的配合,我遇到的一个问题就是操作系统的版本和容器的版本不一致导致安装失败。
1、使用docker安装IRIS Health
安装平台介绍:Ubuntu18.04及docker 20.10
要求满足的容器版本20.04
安装过程中遇到的问题:注意linux的发行版本,必须严格遵守,本人在安装过程中最开始使用的是Ubuntu20,使用docker pull containers.intersystems.com/intersystems/iris-community:2022.1.0.209.0 命令可以顺利拉取镜像,但是在启动容器的过程中,一直失败,参考社区中有关启动失败时,设置cpu等限制sudo docker run --name my-iris --cpuset-cpus 0-7 -d store/intersystems/iris-community:2021.2.0.649.0,同样失败,最后发现是ubuntu的版本问题导致的,我最开始只关注了docker的版本,后来使用ubuntu18.04,即可顺利拉取镜像并启动容器。
附:1、查看ubuntu版本命令 cat /proc/version
2、查看docker版本命令 dicker version
2、windows安装IRIS Health
安装平台介绍:windows10(64位)
硬件介绍:16核cpu,32G运存,500G存储。注:因为本人采用的是虚拟机,所以各项配置初始时调整的很高,安装后发现社区版对各种性能有限制,例如cpu最多用8个,内存限制等,所以硬件环境无需太高,但是也不能太低,像windows10这种,首先要保证系统可以顺利安装,
在配置方面,Win10的配置要求其实并不高,具体配置如下:
CPU:1GHz或更快的处理器
RAM:1GB(32位)或2GB(64位)
HDD:16GB(32位操作系统)或20GB(64位操作系统)
显卡:DirectX 9或更高版本(包含WDDM 1.0驱动程序)
显示器:1024x600分辨率
简而言之,只要满足或者高于以上要求即可安装。
但是考虑到iris还要占用很大一块运存和存储,所以windows10最少得4G运存和200G存储,这样系统运行不会太卡,iris运行速度也算可以(这个速度我只测试没有运行处理任务的速度)。
安装过程中遇到的问题:1、注意windows10的位数不要安装32位的操作系统,同时IRIS不支持windows7,一开始没注意,一直安装失败。
windows确定操作系统版本以及位数的命令不在赘述,google一下,很简单。
下一步计划
平台建好以后开始考虑数据的获取,下一步首先继续熟悉iris产品架构,然后尝试能否实现ETL与IRIS的对接。 好文,期待下一步分享! linux的安装可以参考一下马老师写的这篇文章https://cn.community.intersystems.com/node/516631,很nice
文章
Hao Ma · 三月 26, 2021

# 使用 IRIS 和 Python 创建聊天机器人
本文将展示如何把 InterSystems IRIS 数据库与 Python 集成,以服务于自然语言处理 (NLP) 的机器学习模型。
### 为什么选择 Python?
随着在世界范围内的广泛采用和使用,Python 拥有了出色的社区,以及许多加速器 | 库用于部署任何类型的应用。 如果您感兴趣,请访问 https://www.python.org/about/apps/
### Iris Globals
我接触到 ^globals 后很快就熟悉了,它们可以用作快速获取现成数据模型中数据的方法。 因此,首先,我将使用 ^globals 存储训练数据和对话以记录聊天机器人的行为。
### 自然语言处理
自然语言处理或 NLP 是 AI 的一个主题,它创造了机器从我们的语言阅读、理解含义的能力。 显然,这并不简单,但是我将展示如何在这个广阔而美丽的领域中迈出您的第一步。
### 演示 - 来试试吧
我在这里部署了 Chatbot 应用作为演示: [http://iris-python-suite.eastus.cloudapp.azure.com:8080](http://iris-python-suite.eastus.cloudapp.azure.com:8080)
### 工作原理
### 机器学习
首先要知道与普通软件开发相比,机器学习具有不同的范式。 很难理解的要点是机器学习模型的开发周期。
**浅显解释预警**
一个标准的应用开发周期大概是这样:
开发代码 -> 测试(使用开发数据)-> 部署(真实用户数据)
机器学习代码本身不具有相同的价值。 它会与数据分担责任! 而且不是任意数据,是真实数据! 因为待执行的最终代码是由开发概念和所用数据合并生成。 所以机器学习应用周期类似于:
开发(训练)模型 + 真实数据 -> 验证 -> 部署此模型的结果
### 如何训练模型?
训练模型的技术有很多,每种情况和目标都需要很大的学习曲线。 在本例中,我使用的是 [ChatterBot](https://github.com/gunthercox/ChatterBot) 库,该库封装了一些技术,并提供了训练方法和经过预处理的训练数据,有助于我们关注结果。
### 预训练的模型语言和自定义模型
您可以由此开始拥有一个基本的会话聊天机器人。 您还可以创建所有数据来训练您的聊天机器人,全面满足您的需求,但这在短时间内很难完成。 在这个项目中,我使用 en_core_web_sm 作为对话的基础,并与可以通过[表单](http://iris-python-suite.eastus.cloudapp.azure.com/chatbot-training-data)创建的自定义训练数据合并
### 基础架构

### 在 Python 中使用了什么
在这个应用环境中,我使用了 Python 3.7 和这些模块:
- PyYAML=1.0.0
- chatterbot>=1.0.0
- chatterbot-corpus>=1.2.0
- SQLAlchemy>=1.2
- ./nativeAPI_wheel/irisnative-1.0.0-cp34-abi3-linux_x86_64.whl
### 项目结构
本项目具有简单易懂的结构。 在主文件夹上,有 3 个最重要的子文件夹:
- ./app:具有全部**应用代码**和安装配置。
- ./iris:具有 **InterSystems IRIS dockerfile**,准备服务于应用。
- ./data:通过一个**卷**将主机链接到容器环境
### 应用结构
现在,可以在 ./app 目录下看到一些文件:
- chatbot.py:具有 Web 应用实现
- iris_python_suite.py:具有一些加速器的类,通过 IRIS Native API 与 IRIS 数据库和 Python 搭配使用。
### 数据库结构
此应用使用 Intersystems IRIS 作为存储库,使用的 globals 包括:
- ^chatbot.training.data:以问题和答案的形式存储所有自定义训练数据。
- ^chatbot.conversation:存储所有对话有效负载。
- ^chatbot.training.isupdated:控制训练管道。
### 其他解决方案的产品
我没有为所有对话创建报告,但这不是什么问题,使用全局图形查看器即可跟踪对话。

## 亲自运行应用
### 先决条件
* git
* docker 和 docker-compose(以及 docker 中更多的内存设置,至少 4GB)
* 在您的环境中访问终端
### 步骤
使用 docker-compose,您可以在一个环境中将所有组件和配置轻松转到 iris-python-covid19 文件夹,键入:
```
$ docker compose build
$ docker compose up
```
### 估计转入容器的时间
第一次运行将通过网络链接下载图像和依赖项。 如果持续时间超过 15 分钟,那可能是出现了问题,请随时来这里留言。 第一次运行后,下一次运行会好很多,只需要不到 2 分钟。
### 如果一切正常
一段时间后,您可以打开浏览器并转到地址:
训练数据表单
```
http://localhost:8050/chatbot-training-data
```
聊天机器人
```
http://localhost:8080
```
### 您应该查看 IRIS 管理门户
我暂时使用的是 USER 命名空间
```
http://localhost:9092
user: _SYSTEM
pass: theansweris42
```
### 如果本文对您有帮助或者有您喜欢的内容,请投票:
此应用目前正在参与 Open Exchange 竞赛,您可以在这里给我的应用 **iris-python-suite** 投票 (https://openexchange.intersystems.com/contest/current)