軟件工程師在這個世界上占據著令人興奮的地位。無論技術堆棧或行業如何,我們的任務都是解決直接有助于實現雇主目標的問題。作為獎勵,我們可以利用技術來緩解我們遇到的任何挑戰。
對于這個例子,我想重點關注 pgvector(Postgres 的開源矢量相似性搜索)如何實現用于識別企業數據中存在的數據相似性。
一個簡單的用例
舉一個簡單的例子,我們假設營銷部門需要為他們計劃發起的活動提供幫助。目標是覆蓋與軟件行業密切相關的行業中的所有 Salesforce 帳戶。
最后,他們希望重點關注前三個最相似行業的客戶,以便將來能夠使用此工具來查找其他行業的相似之處。如果可能的話,他們希望能夠提供所需數量的匹配行業,而不是總是返回前三名。
高級設計
此用例以執行相似性搜索為中心。雖然可以手動完成此練習,但我會想到 Wikipedia2Vec 工具,因為已經預先訓練好的嵌入為多種語言創建。詞嵌入(也稱為向量)是包含句法和語義信息的詞的數字表示。通過將單詞表示為向量,我們可以從數學上確定哪些單詞在語義上與其他單詞“更接近”。
在我們的示例中,我們還可以編寫一個簡單的 Python 程序來為 Salesforce 中配置的每個行業創建詞向量。
pgvector 擴展需要 Postgres 數據庫。但是,我們示例的企業數據當前駐留在 Salesforce 中。幸運的是,Heroku Connect 提供了一種將 Salesforce 帳戶與 Heroku Postgres 同步的簡單方法,將其存儲在名為 <代碼> salesforce.account 代碼>。然后,我們將有另一個名為 salesforce.industries 的表,其中包含 Salesforce 中的每個行業(作為 VARCHAR 鍵)及其關聯的詞向量。
借助 Postgres 中的 Salesforce 數據和詞向量,我們將使用 Java 和 Spring Boot 創建一個 RESTful API。該服務將執行必要的查詢,并以 JSON 格式返回結果。
我們可以這樣說明解決方案的高級視圖:

源代碼將駐留在 GitLab 中。發出 git push heroku 命令將觸發 Heroku 中的部署,從而引入營銷團隊可以輕松使用的 RESTful API。
構建解決方案
高層設計到位后,我們就可以開始構建解決方案了。使用 Salesforce 登錄,我能夠導航到帳戶屏幕來查看此練習的數據。以下是企業數據首頁的示例:

創建 Heroku 應用程序
為此,我計劃使用 Heroku 來解決營銷團隊的請求。我登錄到 Heroku 帳戶并使用創建新應用程序按鈕建立一個名為 similarity-search-sfdc 的新應用程序:

創建應用程序后,我導航到資源選項卡以查找 Heroku Postgres 插件。我在附加組件搜索字段中輸入了“Postgres”。

從列表中選擇Heroku Postgres后,我選擇了Standard 0計劃,但pgvector是可在運行 PostgreSQL 15 或 beta Essential 層數據庫的標準層(或更高)數據庫產品上使用。

當我確認該附加組件時,Heroku 生成并提供了一個 DATABASE_URL 連接字符串。我在應用程序的設置選項卡的配置變量部分中找到了它。我使用此信息連接到我的數據庫并啟用 pgvector 擴展,如下所示:
?
創建擴展向量;
接下來,我搜索并找到了 Heroku Connect 插件。我知道這將為我提供一種連接到 Salesforce 中的企業數據的簡單方法。

對于本練習,免費的演示版計劃效果很好。

此時,similarity-search-sfdc 應用的資源選項卡如下所示:

我按照“設置 Heroku Connect”說明鏈接了我的Heroku Connect 的 Salesforce 帳戶。然后,我選擇了 Account 對象進行同步。完成后,我能夠在 Heroku Connect 和底層 Postgres 數據庫中看到相同的 Salesforce 帳戶數據。

從 SQL 角度來看,我所做的結果是創建了一個具有以下設計的 salesforce.account 表:
?
創建表 salesforce.account
(
創建日期時間戳,
已刪除布爾值,
名稱 varchar(255),
systemmodstamp 時間戳,
帳號 varchar(40),
行業 varchar(255),
sfid varchar(18),
序列號
首要的關鍵,
_hc_lastop varchar(32),
_hc_err 文本
);
生成向量
為了使相似性搜索按預期運行,我需要為每個 Salesforce 帳戶行業生成詞向量:
- 服裝
- 銀行業務
- 生物技術
- 施工
- 教育
- 電子產品
- 工程
- 娛樂
- 食品和飲料
- 財務
- 政府
- 醫療保健
- 熱情好客
- 保險
- 媒體
- 非營利性
- 其他
- 休閑
- 零售
- 運送
- 技術
- 電信
- 交通
- 實用程序
由于主要用例表明需要找到軟件行業的相似之處,因此我們也需要為該行業生成一個詞向量。
為了使本練習保持簡單,我使用 Python 3.9 和一個名為 embed.py 的文件手動執行此任務,如下所示:
?
從 wikipedia2vec 導入 Wikipedia2Vec
wiki2vec = Wikipedia2Vec.load('enwiki_20180420_100d.pkl')
print(wiki2vec.get_word_vector('軟件').tolist())
請注意 – get_word_vector() 方法需要使用小寫字母表示行業。
運行 python embed.py 為 software 單詞生成以下單詞向量:
?
[-0.40402618050575256、0.5711150765419006、-0.7885153293609619、-0.15960034728050232、-0.5692323446273804、
0.005377458408474922、-0.1315757781267166、-0.16840921342372894、0.6626015305519104、-0.26056772470474243、
0.3681095242500305、-0.453583300113678、0.004738557618111372、-0.4111144244670868、-0.1817493587732315、
-0.9268549680709839、0.07973367720842361、-0.17835664749145508、-0.2949991524219513、-0.5533796548843384、
0.04348105192184448, -0.028855713084340096, -0.13867013156414032, -0.6649054884910583, 0.03129105269908905,
-0.24817068874835968、0.05968991294503212、-0.24743635952472687、0.20582349598407745、0.6240783929824829、
0.3214546740055084、-0.14210252463817596、0.3178422152996063、0.7693028450012207、0.2426985204219818、
-0.6515568494796753、-0.2868216037750244、0.3189859390258789、0.5168254971504211、0.11008890718221664、
0.3537853956222534、-0.713259220123291、-0.4132286608219147、-0.026366405189037323、0.003034653142094612、
-0.5275223851203918、-0.018167126923799515、0.23878540098667145、-0.6077089905738831、0.5368344187736511、
-0.1210874393582344、0.26415619254112244、-0.3066694438457489、0.1471938043832779、0.04954215884208679、
0.2045321762561798、0.1391817331314087、0.5286830067634583、0.5764685273170471、0.1882934868335724、
-0.30167853832244873、-0.2122340053319931、-0.45651525259017944、-0.016777794808149338、0.45624101161956787、
-0.0438646525144577, -0.992512047290802, -0.3771328926086426, 0.04916151612997055, -0.5830298066139221,
-0.01255014631897211、0.21600870788097382、-0.18419665098190308、0.1754663586616516、-0.1499166339635849、
-0.1916201263666153、-0.22884036600589752、0.17280352115631104、0.25274306535720825、0.3511175513267517、
-0.20270302891731262、-0.6383468508720398、0.43260180950164795、-0.21136239171028137、-0.05920517444610596、
0.7145522832870483、0.7626600861549377、-0.5473887920379639、0.4523043632507324、-0.1723199188709259、
-0.10209759324789047、-0.5577948093414307、-0.10156919807195663、0.31126976013183594、0.3604489266872406、
-0.13295558094978333、0.2473849356174469、0.278846800327301、-0.28618067502975464、0.00527254119515419]
創建行業表
為了存儲詞向量,我們需要使用以下 SQL 命令向 Postgres 數據庫添加一個 industries 表:
?
創建表 salesforce.industries
(
name varchar not null 約束 Industries_pk 主鍵,
嵌入向量(100)不為空
);
創建industries表后,我們將插入每個生成的詞向量。我們使用類似于以下的 SQL 語句來執行此操作:
?
插入 salesforce.industries
(名稱、嵌入)
價值觀
('軟件','[-0.40402618050575256, 0.5711150765419006, -0.7885153293609619, -0.15960034728050232, -0.5692323446273804, 0.00537745840 8474922, -0.1315757781267166, -0.16840921342372894, 0.6626015305519104, -0.26056772470474243, 0.3681095242500305, -0.453583300113 678, 0.004738557618111372, -0.4111144244670868, -0.1817493587732315, -0.9268549680709839, 0.07973367720842361, -0.17835664749145508, -0.2949991524219513, -0.5533796548843384, 0.04348105192184448, -0.028855713084340096 , -0.13867013156414032, -0.6649054884910583, 0.03129105269908905, -0.24817068874835968, 0.05968991294503212, -0.24743635952472687 , 0.20582349598407745, 0.6240783929824829, 0.3214546740055084, -0.14210252463817596, 0.3178422152996063, 0.7693028450012207, 0 .2426985204219818,-0.6515568494796753, -0.2868216037750244、0.3189859390258789、0.5168254971504211、0.11008890718221664、0.3537853956222534、-0.713259220123291、-0.4 132286608219147, -0.026366405189037323, 0.003034653142094612, -0.5275223851203918, -0.018167126923799515, 0.23878540098667145, -0 .6077089905738831, 0.5368344187736511, -0.1210874393582344, 0.26415619254112244, -0.3066694438457489, 0.1471938043832779, 0.049 54215884208679, 0.2045321762561798, 0.1391817331314087 , 0.5286830067634583, 0.5764685273170471, 0.1882934868335724, -0.30167853832244873, -0.2122340053319931, -0.45651525259017944, -0.016777794808149338, 0.45624101161956787, -0.0438646525144577, -0.992512047290802, -0.3771328926086426, 0.04916151612997055, -0 .5830298066139221, -0.01255014631897211, 0.21600870788097382, -0.18419665098190308, 0.1754663586616516, -0.1499166339635849, -0.1 916201263666153 , -0.22884036600589752, 0.17280352115631104, 0.25274306535720825, 0.3511175513267517, -0.20270302891731262, -0.638346850872039 8, 0.43260180950164795, -0.21136239171028137, -0.05920517444610596, 0.7145522832870483, 0.7626600861549377, -0.5473887920379639, 0.4523043632507324, -0.1723199188709259, -0.10209759324789047, -0.5577948093414307, -0.10156919807195663, 0.31126976013183594, 0 .3604489266872406,- 0.13295558094978333、0.2473849356174469、0.278846800327301、-0.28618067502975464、0.00527254119515419]
');
請注意 – 雖然我們使用小寫代表軟件行業(軟件)創建了詞向量,但 industries.name 列需要與大寫行業相匹配名稱(軟件)。
將所有生成的詞向量添加到 industries 表后,我們就可以將重點轉向引入 RESTful API。
引入 Spring Boot 服務
此時,我作為一名軟件工程師的熱情開始高漲,因為我已經做好了一切準備來解決眼前的挑戰。
接下來,使用 Spring Boot 3.2.2 和 Java (temurin) 17,我在 IntelliJ IDEA 中創建了 similarity-search-sfdc 項目,并具有以下 Maven 依賴項: p>
?
我為 Account 對象和 Industry(嵌入)對象創建了簡化的實體,這些實體與之前創建的 Postgres 數據庫表對齊。
?
@AllArgsConstructor
@NoArgs構造函數
@數據
@實體
@Table(名稱=“帳戶”,模式=“銷售人員”)
公開課賬戶{
@ID
@Column(名稱=“sfid”)
私有字符串 ID;
私有字符串名稱;
私營弦產業;
}
@AllArgsConstructor
@NoArgs構造函數
@數據
@實體
@Table(名稱=“行業”,模式=“銷售人員”)
公開課行業{
@ID
私有字符串名稱;
}
使用 JpaRepository 接口,我添加了以下擴展以允許輕松訪問 Postgres 表:
?
來自 salesforce.industries
WHERE 名稱 = ‘軟件’)
限制 3)
按名稱排序;” data-lang=”text/x-sql”>
SELECT sfid、名稱、行業
來自 salesforce.account
哪里的行業
輸入(選擇名稱
來自 salesforce.industries
WHERE 名稱 != '軟件'
按嵌入排序
<->(選擇嵌入
來自 salesforce.industries
WHERE 名稱 = '軟件')
限制 3)
按名稱排序;
從那里,我構建了 AccountsService 類來與 JPA 存儲庫交互:
?
最后,我讓 AccountsController 類提供 RESTful 入口點并連接到 AccountsService:
?
curl --location 'https://HEROKU-APP-ROOT-URL/accounts/similarities?industry=Software&limit=3'
RESTful API 返回 200 OK HTTP 響應狀態以及以下負載:
?
[
{
“id”:“001Kd00001bsP80IAE”,
"name": "CleanSlate 科技集團",
“行業”:“技術”
},
{
“id”:“001Kd00001bsPBFIA2”,
“名稱”:“CMG 全球”,
“行業”:“媒體”
},
{
“id”:“001Kd00001bsP8AIAU”,
"name": "開發者聚光燈",
“行業”:“技術”
},
{
“id”:“001Kd00001bsP8hIAE”,
"name": "蛋頭",
“行業”:“電子”
},
{
“id”:“001Kd00001bsP85IAE”,
“名稱”:“Marqeta”,
“行業”:“技術”
}
]
因此,技術、媒體和電子行業是與最接近的行業本例中的軟件行業。
現在,營銷部門有了一份可以聯系以開展下一次營銷活動的帳戶列表。
結論
幾年前,我花在玩軍團要塞 2多人視頻游戲上的時間比我愿意承認的還要多。這是 2012 年一次非常有趣的活動的屏幕截圖:

那些熟悉我生活這方面的人可能會告訴你,我默認選擇的玩家職業是士兵。這是因為士兵的生命值、移動力、速度和火力具有最佳的平衡。
我覺得軟件工程師就是現實世界中的“士兵階層”,因為我們可以適應任何情況,專注于高效地提供滿足期望的解決方案。
幾年來,我一直專注于以下使命宣言,我認為它可以適用于任何 IT 專業人員:
<塊引用>
“將時間集中在提供可擴展知識產權價值的特性/功能上。利用框架、產品和服務來完成其他一切。”
– J.維斯特
塊引用>
在本文的示例中,我們能夠利用 Heroku Connect 將企業數據與 Postgres 數據庫同步。安裝 pgvector 擴展后,我們從這些 Salesforce 帳戶中為每個獨特的行業創建了詞向量。最后,我們引入了 Spring Boot 服務,該服務簡化了查找行業與另一個行業最接近的 Salesforce 帳戶的過程。
我們利用現有的開源技術、添加的小型 Spring Boot 服務和 Heroku PaaS 快速解決了這個用例 – 完全遵循我的使命宣言。我無法想象如果沒有這些框架、產品和服務,需要多少時間。
如果您有興趣,可以在 GitLab。
祝你有美好的一天!