検索

記事
· 2025年10月27日 1m read

Connect to SQL server via Windows Auth

I was facing the same issue as Jerry faced when connecting IRIS to SQL server. My ODBC connection is configured to authenticate via windows authentication.

Configure IRIS ODBC connection with Windows authentication using a
 

How I fixed it for myself?

Root cause

  • The SQL Server DSN was set to Windows Integrated Authentication.
  • IRIS opens the ODBC connection via irisdb.exe, which runs under the IRIS Windows services’ logon account.
  • My IRIS services were running as LocalSystem, so SQL saw the machine account <ORGNAME>\<ASSETID>$. SQL had no login for that identity → 18456 / 28000 “Login failed for user ‘…$’”.

I changed both IRIS services to run as a domain identity that SQL Server trusts: <WINDOWSACCOUNTUSERNAME> = <Orgname>\<Username>.

Commands used (elevated CMD):

"C:\InterSystems\IRIS\bin\iris" stop <instance> quietly "C:\InterSystems\IRIS\bin\IRISinstall.exe" setserviceusername <instance> "<YOURWINDOWSACCOUNTUSERNAME>" "<password>" "C:\InterSystems\IRIS\bin\iris" start <instance>

 

That utility updates:

  • InterSystems IRIS Controller for <instance>
  • InterSystems IRIS for <instance>
    …adds the account to IRISServices and IRIS_Instance_<instance> groups, and grants required NTFS rights.

 

Please let me know if there is a better way to do this.

ディスカッション (0)2
続けるにはログインするか新規登録を行ってください
InterSystems公式
· 2025年10月26日

InterSystems 云服务 - 版本 25.22.1

概述

此版本重点聚焦于多个InterSystems云服务在升级可靠性、安全功能扩展以及支持体验优化方面的提升。通过该版本,包括 FHIR Server、InterSystems Data Fabric Studio (IDS)、IDS with Supply Chain 和 IRIS Managed Services 在内的所有主要产品,现均支持高级安全功能,从而提供了统一且增强的安全态势。

新功能和增强功能

类别

功能/改进

详细信息

平台升级

FHIR 服务器升级增强功能

改进了 FHIR 服务器升级的可靠性、验证和自动化,减少了停机时间,确保了更平稳的过渡。

 

IDS 升级改进

增强了 InterSystems Data Fabric Studio (IDS) 的升级工作流程,以提高一致性并减少操作中断。

 

带供应链的 IDS 升级改进

带有供应链的 IDS 升级现在更快、更灵活,并具有更好的依赖性处理和验证检查功能。

安全性

高级安全扩展

高级安全功能可提供增强的防火墙管理、加密控制和实时威胁保护,现在可用于
- FHIR 服务器
- IDS
- 带供应链的 IDS
- IRIS 托管服务

用户管理

改进租户用户邀请

简化和更可靠的租户用户邀请流程,改善入职体验并减少邀请错误。

用户体验

更清晰的使用条款审批

更新的信息和布局使用户在审查和批准服务使用条款时更加透明。

技术支持

更新了支持服务级别协议

更新了支持服务级别协议,大大缩短了响应时间,并更频繁地更新未结案例,确保更快地解决问题并改善沟通。

建议采取的行动

  • 查看并让您的团队了解并熟悉服务所提供的新型高级安全选项。
  • 验证租户邀请工作流程,确保所有受邀用户及时收到并接受访问权限。
  • 查看更新的支持 SLA 文档,了解有关新响应和更新时限的详细信息。

支持

如需帮助或了解有关这些更新的更多信息,请通过 iService 或 InterSystems 云服务门户打开支持案例。

©2025 InterSystems Corporation。版权所有。

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください
ダイジェスト
· 2025年10月26日

InterSystems 开发者社区中文版:每周摘要(2025年10月20日-26日)

十月 20 - 26, 2025Week at a GlanceInterSystems Developer Community
記事
· 2025年10月26日 14m read

 ベクトル検索のサンプルをやってみた

コミュニティの皆さんこんにちは。
 

ベクトル検索関連の処理が完全にノーマークだった私が、一先ず「やってみよう!」との事で、2つの動画のサンプルを実行してみました。
Pythonは初心者なので、アレな箇所があっても目をつぶっていただけると幸いです。

また、間違っている箇所があったら、ご指摘いただけると幸いです。



■参考にした動画

■参考にしたコミュニティ記事

 

【目的】

本記事では、動画で紹介された内容を実際にIRIS環境上で実行できるよう、具体的な環境構築とコーディングを記載致します。
コミュニティの皆さんが簡単に試せるようになれば幸いです。

またGithubにサンプルソースを配置しているので、必要な方は参考にして下さい。

 

【準備】

■作業環境

※環境作成方法に問題のない方は、読み飛ばしていただいて構いません。

 

項目 バージョン情報・他
OS WIndowsServer2019
IRIS IRIS Community 2025.2.0.227.0
Python 3.12.10
開発環境 VS Code 1.105.1

 

🔸IRISのライセンス
 ベクトル検索を行うので、ライセンス関連からCommunityを選択しました。入手先はココです。

🔸VS Code
 IRIS 2025.2は、既にApache Webサーバスタジオが廃止されています。
 そのため、IISとVS Codeをインストールする必要があります。
 VS Codeの入手先はココからで、設定方法はコミュニティの記事を参照してください。

🔸Python
 IRIS 2025.2.0.227.0でPython3.14は動作しません(この先のバージョンに期待です)。
 Python3.13はインストールするライブラリが動作しないようで、3.12系を使用する事になりました。
 Python 3.12.10の入手先はココからで、設定方法はコミュニティの記事を参照してください。

 

■Pythonライブラリのインストール

Pythonの実行に使用したライブラリをインストールします。
コマンドプロンプトにて実行して下さい。

rem データセット用
pip install datasets==2.19.0
pip install tensorflow
pip install tensorflow-datasets==4.8.3

rem 検索・IRISデータ作成用
pip install pandas
pip install sentence_transformers
pip install tf-keras
pip install requests
pip install sqlalchemy-iris

rem 両方で使用 
pip install pyarrow

インストールしたライブラリの中に、IRISと接続する「sqlalchemy-iris」があります。
詳細はコミュニティの記事を参照してください。

 

■ IRIS側はライブラリの追加は不要です。
 もし動かない場合は、「python -m pip –-target <iris_dir>\mgr\pytyon <module>」でインストールしてください。

 

【実行】

■「ベクトル検索のご紹介」編

 

<<テストデータの作成>>

先ずは、Hugging Faceより、cc100のデータセットをダウンロードします。

import os
os.environ["HF_DATASETS_CACHE"] = "D:\\Python\\HuggingFaceCache" # Cache保存先指定
from datasets import load_dataset

dataset = load_dataset("cc100", lang="ja", trust_remote_code=True)
#getlist = dataset["train"].select(range(100000)) # レコード数を制限する場合は開放する
output_path = "D:\\Python\\cc100_Parquet\\cc100-ja_sharded2.parquet" # parquetファイル保存先
dataset["train"].to_parquet(output_path)
#getlist.to_parquet(output_path) # レコード数を制限する場合はこちら

cc100はかなりファイルが大きく、HuggingFaceCacheは160GB  parquetファイルは44.5GBになり、合わせて204.5GBの空き容量が必要になります。
また、作成時間も余裕の10時間オーバーなので、気長に覚悟を持ってお待ちください。
 ※2回目からはCacheが効いているため、多少早くなります。

 

後々、2.02GBのparquetファイルの存在を知りました。
ココからダウンロードしても問題ないと思います。

 

<<IRISデータ作成>>

先ほど作成したparquetファイルから10万件読み込み、モデル「stsb-xlm-r-multilingual」を使いベクトル化してIRISに保存しています。

import pandas as pd
from sentence_transformers import SentenceTransformer
from sqlalchemy import create_engine, text
from pyarrow.parquet import ParquetFile
import pyarrow as pa

# parquetファイル読み込み
pf = ParquetFile(r"D:\Python\cc100_Parquet\cc100-ja_sharded.parquet")
first_rows = next(pf.iter_batches(batch_size = 100000))
df = pa.Table.from_batches([first_rows]).to_pandas()
df = df.replace("\n", "", regex=True)

# モデルを使いベクトル化
model = SentenceTransformer('stsb-xlm-r-multilingual')
embeddings = model.encode(df['text'].tolist(), normalize_embeddings=True)
df['text_vector'] = embeddings.tolist()

# IRISへ接続
username = '_system'
password = 'SYS'
hostname = 'localhost'
port = 1972            # スーパーサーバポート
namespace = 'USER'
CONNECTION_STRING = f"iris://{username}:{password}@{hostname}:{port}/{namespace}"
engine = create_engine(CONNECTION_STRING)

# テーブル作成
with engine.connect() as conn:
    with conn.begin():
        sql = f"""
            CREATE TABLE vectortest(
                contents VARCHAR(4096),
                contents_vector VECTOR(DOUBLE, 768)
            )
            """
        result = conn.execute( text(sql) )

# データ作成
with engine.connect() as conn:
    with conn.begin():
        for index, row in df.iterrows():
            sql = text(
                """
                    INSERT INTO vectortest
                    (contents, contents_vector)
                    VALUES (:contents, TO_VECTOR(:contents_vector))
                """
            )
            conn.execute(sql, {
                'contents': row['text'],
                'contents_vector': str(row['text_vector'])
            })

 

<<動作検証(Python)>>

ベクトル検索する際は、検索したい文字列を同じモデルでベクトル化し、ドット積(VECTOR_DOT_PRODUCT)を求めます。

import sys
import pandas as pd
from sentence_transformers import SentenceTransformer
from sqlalchemy import create_engine, text

# 引数
args = sys.argv
contents_search = args[1]

# 引数をベクトル化
model = SentenceTransformer('stsb-xlm-r-multilingual')
search_vector = model.encode(contents_search, normalize_embeddings=True).tolist()

# IRISへ接続
username = '_system'
password = 'SYS'
hostname = 'localhost'
port = 1972
namespace = 'USER'
CONNECTION_STRING = f"iris://{username}:{password}@{hostname}:{port}/{namespace}"
engine = create_engine(CONNECTION_STRING)

# 検索
with engine.connect() as conn:
    with conn.begin():
        sql = text("""
            SELECT TOP 5 contents, VECTOR_DOT_PRODUCT(contents_vector, TO_VECTOR(:search_vector, double, 768)) as sim FROM vectortest
            ORDER BY sim DESC
        """)

        results = conn.execute(sql, {'search_vector': str(search_vector)}).fetchall()

# 検索結果を出力
result_df = pd.DataFrame(results, columns=['contents', 'sim'])
pd.set_option('display.max_colwidth', None)
print(result_df)

使い方は、コマンドプロンプトにて下記コマンドを実行します。

python vectorsearch.py 大都市での生活は便利な反面、混雑や環境の悪さなどの問題もある。


<<動作検証(IRIS)>>

Pythonライブラリは、XDataブロックで読み込みました。
 ※各関数でライブラリを読み込むのが面倒だっただけです

XData %import [ MimeType = application/python ]
{
import iris
import pandas as pd
from sentence_transformers import SentenceTransformer
from pyarrow.parquet import ParquetFile
import pyarrow as pa
import datetime
}

ベクトル検索はObjectScriptで記述しています。
また、検索文字列をベクトル化する関数「Comvert()」はPythonで記述しています。

ObjectScriptとPythonを混合して利用できるのは便利ですよね。

ClassMethod Search(txt As %String = "")
{
    q:($g(txt)="")

    s txt = ..Convert(txt)
    s txt = $tr(txt, "[]")

    s query(1) = "select top 5 VECTOR_DOT_PRODUCT(contents_vector, TO_VECTOR(?, DOUBLE, 768)) as sim, contents"
    , query(2) = "from vectortest order by sim desc"
    , query = 2
    w !,"実行"
    s rset = ##class(%SQL.Statement).%ExecDirect(.stmt, .query, .txt)
    while rset.%Next() {
        w !,rset.%Get("contents")
    }
}
ClassMethod Convert(text As %String) As %String [ Language = python ]
{
    model = SentenceTransformer('stsb-xlm-r-multilingual')
    search_vector = model.encode(text, normalize_embeddings=True).tolist()
    return str(search_vector)
}

 

実行結果は下記になります。

 

 

<<IRISからのベクトルデータ登録>>

‼ IRISからPythonの関数を繰り返し実行する際は、Python処理に「gc.collect()」を加える必要がありました。

今回は、ループ処理の最後に追記しています。

ClassMethod makeData(count As %Integer = 100000) [ Language = python ]
{
    pf = ParquetFile(r"D:/Python/cc100_Parquet/cc100-ja_sharded.parquet")
    first_rows = next(pf.iter_batches(batch_size = count))
    df = pa.Table.from_batches([first_rows]).to_pandas()
    df = df.replace("\n", "", regex=True)

    for index,row in df.iterrows():
        txt = row['text']
        iris.cls('dev.Vector').saveData(txt)
        
        gc.collect()
}
ClassMethod saveData(text As %String)
{
    s cnvTxt = $tr(..Convert(text), "[]")
    &sql(insert into dev.SearchData (txt, vec) values(:text, TO_VECTOR(:cnvTxt, double, 768)))
}

 

この処理(gc.collect)を入れないと、Python関数を呼び出す度に使用メモリ量が増加していき、最終的にはエラーが発生して処理が終了しました。
 → 16GBのメモリ量では、30件のレコード登録すら行えませんでした。
 → エラーの内容は、<Session disconnected>です。

 

【エラー発生直前のメモリ使用量の推移】

 

対策を行うとメモリの開放が都度行われて、エラーになることなく処理が完了しました。

 

皆様も、Pythonの関数を何度も呼び出す際は、メモリの使用量にお気を付けください。

 

 

■「テキストから画像検索」編

 

<<前程>>

Hugging faceのドキュメントを読むと、画像のエンコード方法は下記記述になるようです。

img_emb = model.encode(Image.open('two_dogs_in_snow.jpg'))

文字検索時は、引数に「normalize_embeddings=True」が追加していましたが、今回は付与されていません。

調べてみると、デフォルト値は「False」で、下記意味があるようです。

normalize_embeddings 説明
True ドット積を使用する(高速)
False コサイン類似度を使用する

 

今回は、引数無しのデフォルト値(False)なので、コサイン類似度(VECTOR_COSINE)を使用すれば良いと考えます。

 

<<テストデータの作成>>

先ずは、Hugging Faceより、画像のデータセットをダウンロードします。

import os
os.environ["HF_DATASETS_CACHE"] = "D:\\Python\\HuggingFaceCache_image" # Cacheの出力先
from datasets import load_dataset

dataset = load_dataset("recruit-jp/japanese-image-classification-evaluation-dataset")

output_path = "D:\\Python\\image\\recruit-jp.parquet" # parquetファイルの出力先
dataset["train"].to_parquet(output_path)

cc100とは異なり容量の暴力性は少ないです。Cacheで2.36MB、parquetファイルで285KBしかありません。
データセットの中身は画像のurl等で、文字列のみです。

 

<<IRISデータクラスの作成>>

Class dev.ImageData Extends %Persistent [ SqlRowIdPrivate ]
{

Parameter USEEXTENTSET = 1;
Index DDLBEIndex [ Extent, SqlName = "%%DDLBEIndex", Type = bitmap ];
Index HNSWIndex On (imgvec) As %SQL.Index.HNSW(Distance = "Cosine") [ SqlName = HNSWIndex, Type = bitmap ];
Property url As %String(MAXLEN = 256) [ SqlColumnNumber = 2 ];
Property imgvec As %Vector(DATATYPE = "float", LEN = 512) [ SqlColumnNumber = 3 ];
}

 

<<IRISデータ作成>>

先ほど作成したparquetファイルを読み込み、urlから画像を取得し、モデル「clip-ViT-B-32」でベクトル化してIRISに保存しています。
また、コサイン類似度を使用する為、encode()時の引数にnormalize_embeddingsは指定していません(default=False)。

📒いくつかのurlは画像が存在していませんでした。
 そのため、画像が存在しないurlは除外する処理を入れました。

from pyarrow.parquet import ParquetFile
import pyarrow as pa
from sentence_transformers import SentenceTransformer
from sqlalchemy import create_engine, text
from PIL import Image
import requests

pf = ParquetFile(r"D:\Python\image\recruit-jp.parquet")
#first_rows = next(pf.iter_batches(batch_size = 50))
first_rows = next(pf.iter_batches())
df = pa.Table.from_batches([first_rows]).to_pandas()
df = df.replace("\n", "", regex=True)

print(df.head(5)) # id, license, license_urll, url, category
# 画像化
def load_image(url_or_path):
    try:
        urls = url_or_path.split('_o')
        newUrl = urls[0] + '_b' +  urls[1] # #newUrl = urls[0] + '_c' +  urls[1]
        if url_or_path.startswith("http://") or url_or_path.startswith("https://"):
            return Image.open(requests.get(newUrl, stream=True).raw)
        else:
            return Image.open(url_or_path)
    except Exception as e:
        print(repr(e) +":"+ url_or_path)
        return ''
imgModel = SentenceTransformer('clip-ViT-B-32')

# images = [load_image(img) for img in df['url']]
images = []
urlList = []
imgVec = []
count = 0
for img in df['url']:
    count += 1
    imgObj = load_image(img)
    if not imgObj == '':
        images.append(imgObj)
        urlList.append(img)
    else:
        print(str(count))

embeddings = imgModel.encode(images)
imgVec = embeddings.tolist()

print(df.head(5))


# ------------------------------------------------
username = '_system'
password = 'SYS'
hostname = 'localhost'
port = 1972
namespace = 'TESTAI'
CONNECTION_STRING = f"iris://{username}:{password}@{hostname}:{port}/{namespace}"
engine = create_engine(CONNECTION_STRING)

with engine.connect() as conn:
    with conn.begin():
        for vec, url in zip(imgVec, urlList):
            sql = text(
                """
                    INSERT INTO dev.ImageData (url, imgvec)
                    VALUES (:url, TO_VECTOR(:imgvec))
                """
            )
            conn.execute(sql, {
                'url': url,
                'imgvec': str(vec)
            })

 

<<動作検証(Python)>>

こちらもhuggingface のドキュメントを参照すると、使い方が記載されています。

エンコード方法と検索方法は「コサイン類似度(VECTOR_COSINE)」を使用すると記載があります。

text_model = SentenceTransformer('sentence-transformers/clip-ViT-B-32-multilingual-v1')
text_embeddings = text_model.encode(texts)

# Compute cosine similarities:(コサイン類似度を計算します。)
cos_sim = util.cos_sim(text_embeddings, img_embeddings)

 

ドキュメントに沿って文字列をモデル「sentence-transformers/clip-ViT-B-32-multilingual-v1」でベクトル化し、コサイン類似度で検索を行います。

import sys
import pandas as pd
from sentence_transformers import SentenceTransformer
from sqlalchemy import create_engine, text

args = sys.argv
contents_search = args[1]

# 引数のベクトル化
txtModel = SentenceTransformer('sentence-transformers/clip-ViT-B-32-multilingual-v1')
search_vector = txtModel.encode(contents_search).tolist()
print(len(search_vector))

# IRIS接続
username = '_system'
password = 'SYS'
hostname = 'localhost'
port = 1972
namespace = 'TESTAI'
CONNECTION_STRING = f"iris://{username}:{password}@{hostname}:{port}/{namespace}"
engine = create_engine(CONNECTION_STRING)

# 検索処理実行
with engine.connect() as conn:
    with conn.begin():
        sql = text("""
            SELECT TOP 5 url, VECTOR_COSINE(imgvec, TO_VECTOR(:txtvec, float, 512)) as sim FROM dev.ImageData
            ORDER BY sim DESC
        """)

        results = conn.execute(sql, {'txtvec': str(search_vector)}).fetchall()

# 検索結果出力
result_df = pd.DataFrame(results, columns=['sim', 'url'])
print(result_df)

使い方は、コマンドプロンプトにて下記コマンドを実行します。

python imagesearch.py 黄色い花

 

<<動作検証(IRIS)>>

文字列から「画像」を検索する試みです。
検索した画像をブラウザで参照したいと思い、RESTサービスを使ってブラウザに結果を返却するようにしました。

 

ブラウザ側へ検索結果を返すため、%DynamicArrayを利用しています。

ClassMethod SearchImg(txt As %String) As %DynamicArray
{
    q:($g(txt)="")

    s txt = ..ConvertImg(txt)
    s txt = $tr(txt, "[]")

    s query(1) = "SELECT TOP 5 url, VECTOR_COSINE(imgvec, TO_VECTOR(?, float, 512)) as sim"
    , query(2) = "FROM dev.ImageData order by sim desc"
    , query = 2
    s ary = []
    s rset = ##class(%SQL.Statement).%ExecDirect(.stmt, .query, .txt)
    while rset.%Next() {
        s url = $replace(rset.%Get("url"),"_o.jpg","_b.jpg")
        d ary.%Push({
            "imgid":(url),
            "sim":(rset.%Get("sim"))
        })
    }
    q ary
}

文字列をベクトル化する関数はPythonで記述します。

ClassMethod ConvertImg(txt As %String) As %String [ Language = python ]
{
    text_model = SentenceTransformer('sentence-transformers/clip-ViT-B-32-multilingual-v1')
    text_embeddings = text_model.encode(txt).tolist()
    return str(text_embeddings)
}

RESTクラス(抜粋)

XData UrlMap
{
<Routes>
<Route Url="/sample" Method="GET" Call="GetImage" Cors="true"/>
</Routes>
}

ClassMethod GetImage() As %Status
{
    s search = $g(%request.Data("searchTxt",1))

    s start = $zh
    , getImgs = ##class(dev.Vector).SearchImg(search)
    , end = $zh
    d ##class(%REST.Impl).%WriteResponse({
        "image": (getImgs),
        "time" : (end-start)
    })
    q $$$OK
}

後はブラウザを起動して確認します。

検索文字列は、「黄色い花」「中華料理」「インド料理」「赤い花」「」で試しました。
検索結果の画像に、「何故それが検索されたのか?」ってのが、紛れていますね🤣

 

一先ず再現が出来たっぽいので、良しとさせて下さい。

 

【最後に】

今回は「やってみよう!」の精神で、IRISのベクトル検索に挑戦してみました。

初めて触れると少し複雑に感じる部分もありましたが、一度動作が確認できるとその仕組みの面白さが実感できます。

また、今回の記事を通じて、Pythonや各種モデルのドキュメントにも触れることができ、多くの学びを得ることができました。

 

この記事を通して、IRISのベクトル検索機能に触れる切っ掛けになれば幸いです。

 

 

 

後は、もっと気軽に活用できるよう、ライセンスの方も何とかして欲しいです。
触って感じましたが、素晴らしい機能だと思います。
 

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください
質問
· 2025年10月25日

Stream SVG to load in Logi Reports

How do I take SVG data to be an image in Logi Reports? Now I can take JPG data and render it in Logi Reports. And I can take the SVG data in ObjectScript, but when I view it in Logi Reports, it won't appear. How do I get the code in ObjectScript to appear and be read in Logi Reports?

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください