軟件工程師在這個世界上占據著令人興奮的地位。無論技術堆棧或行業如何,我們的任務都是解決直接有助于實現雇主目標的問題。作為獎勵,我們可以利用技術來緩解我們遇到的任何挑戰。

對于這個例子,我想重點關注 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 表:

SQL

?

創建表 salesforce.account
(
    創建日期時間戳,
    已刪除布爾值,
    名稱 varchar(255),
    systemmodstamp 時間戳,
    帳號 varchar(40),
    行業 varchar(255),
    sfid varchar(18),
    序列號
        首要的關鍵,
    _hc_lastop varchar(32),
    _hc_err 文本
);

生成向量

為了使相似性搜索按預期運行,我需要為每個 Salesforce 帳戶行業生成詞向量:

  • 服裝
  • 銀行業務
  • 生物技術
  • 施工
  • 教育
  • 電子產品
  • 工程
  • 娛樂
  • 食品和飲料
  • 財務
  • 政府
  • 醫療保健
  • 熱情好客
  • 保險
  • 媒體
  • 非營利性
  • 其他
  • 休閑
  • 零售
  • 運送
  • 技術
  • 電信
  • 交通
  • 實用程序

由于主要用例表明需要找到軟件行業的相似之處,因此我們也需要為該行業生成一個詞向量。

為了使本練習保持簡單,我使用 Python 3.9 和一個名為 embed.py 的文件手動執行此任務,如下所示:

Python

?

從 wikipedia2vec 導入 Wikipedia2Vec
wiki2vec = Wikipedia2Vec.load('enwiki_20180420_100d.pkl')
print(wiki2vec.get_word_vector('軟件').tolist())

請注意 – get_word_vector() 方法需要使用小寫字母表示行業。

運行 python embed.pysoftware 單詞生成以下單詞向量:

?

[-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 表:

SQL

?

創建表 salesforce.industries
(
    name varchar not null 約束 Industries_pk 主鍵,
    嵌入向量(100)不為空
);

創建industries表后,我們將插入每個生成的詞向量。我們使用類似于以下的 SQL 語句來執行此操作:

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 依賴項:

XML

?

<依賴項> <依賴關系> org.springframework.boot spring-boot-starter-actuator <依賴關系> org.springframework.boot spring-boot-starter-data-jpa <依賴關系> org.springframework.boot spring-boot-starter-web <依賴關系> com.pgvector pgvector <版本>0.1.4 <依賴關系> org.postgresql postgresql <范圍>運行時 <依賴關系> org.springframework.boot spring-boot-configuration-processor <可選>true <依賴關系> org.projectlombok 龍目島 <可選>true <依賴關系> org.springframework.boot spring-boot-starter-test <范圍>測試

我為 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 存儲庫交互:

爪哇

?

@RequiredArgsConstructor @服務 公共類 AccountsService { 私人最終賬戶存儲庫賬戶存儲庫; 私有最終IndustryRepository IndustriesRepository; 公共集<帳戶> getAccountsBySimilarIndustry(字符串行業, 整數限制) 拋出異常{ List<行業> Industries = IndustriesRepository.findAll(); 如果(行業 。溪流() .map(行業::getName) .anyMatch(行業::等于)) { 返回賬戶存儲庫 .findSimilaritiesForIndustry(行業,限制); } 別的 { 拋出新的異常( “無法定位'”+行業+“'行業”); } } }

最后,我讓 AccountsController 類提供 RESTful 入口點并連接到 AccountsService

爪哇

?

curl --location 'https://HEROKU-APP-ROOT-URL/accounts/similarities?industry=Software&limit=3'

RESTful API 返回 200 OK HTTP 響應狀態以及以下負載:

JSON

?

[
    {
        “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

祝你有美好的一天!

Comments are closed.