Salesforceのビューやレポート。お手軽に情報の取りまとめが出来て便利ですよね。よく使っています。
弊社リバネスのSalesforceは、Herokuで構築したリバネスIDという会員サイトと接続しており、様々な情報が入ってきます。
例えば、リバネス研究費の申請書であったり、TechPLANTERの申請書といった情報が登録されます。
これらの申請書に含まれるフィールドには、ロングテキストエリアやリッチテキストエリアが存在しますが、この中に様々なキーワードが含まれる状態です。
弊社のニーズとしては、これらの情報の中から、ある特定のキーワードを含む人をリスト化してアプローチしたいというものがあり、これまでビューとかレポートで作っていたのですが、ここには大きな落とし穴があることに気付きました。
仕様はこちらに
https://help.salesforce.com/s/articleView?id=sf.fields_rich_text_area_limitations.htm&type=5
レポートの検索条件の「次の文字列を含む」演算子では、リッチテキストエリアまたはロングテキストエリアの最初の 254 文字のみがサポートされます。
え。最初の254文字しかサポートされてなかったの!?と、2022年にもなって今更気付くことに相成りました。
なぜこんなことになるのか
実は、ロングテキストエリアはApexのクエリ言語であるSOQLでもサポートされていません。検索出来ない事になっています。
そしてレポートはSOQLでも出来ないことを実現しているということになる訳です。
では現実的にどうするかというと、一度データローダでデータをダウンロードし、Excel等で検索せざるを得ません。
そんな面倒なことできるか!ってなりますよね。
代替案はないのか
先程SOQLというSELECT文では検索出来ない、レポートやビューも使えないと書いたのですが、ロングテキストエリアを含む検索が実装されている箇所が一つだけあります。
そう、グローバル検索窓です。
こちらについては全ての項目を対象として検索をしてくれます。
唯一の全文検索方法はグローバル検索を使うしか方法がありません。
プログラム的に解決する方法を探すと
SalesforceにはSOQLの他に、SOSLというクエリ言語があります。
SOSLこそがグローバル検索で使われている機能だと言えます。
今回はこちらを使ってサーチエンジンを書いてみました。
リバネス用の検索エンジン Loorule(るーるる)
実装自体はVisualforce + Apexという仕様です。
これで検索すると、こんな形でテーブルが返ってきます。(名前等はDataMask使って変換済み)
なんでテーブルなのかというと、このテーブル自体をコピペしてPardotに取り込むことでメールリストが作成できる為です。
SOSLの書き方
String findQuery = 'FIND \'' + keywords + '\' IN ALL FIELDS RETURNING LnestID_Project_Associations__c(id, theme__c, purpose_of_research__c, research_background__c, research_plans__c, theme_discription_overview__c, social_issues_overview__c, social_issues_longtxt__c, core_tech_overview__c, core_tech_longtxt__c, Native_language_Name__c, company__c, division__c, Title__c, Email_LnestID__c, Lnest_projects_Name__c WHERE status__c != \'Draft\' ORDER BY CreatedDate DESC)';
List<List<sObject>> results = search.query(findQuery);
こんな風になっています。
RETURNINGのあとにsObjectを指定し、カッコの中にかえしてほしいカラム名を指定します。
keywordsには、サーチエンジンに入力した文字列が入ります。
これでList>という、sObjectのリストのリストが返ってきます。
なぜsObject型で受けるのかというと、Findの中では、複数オブジェクトを指定することが出来ます。それが返ってくるからですね。
まとめ
以上で、ロングテキストエリアも対象とするリストを作成することができます。
SOSLこれまで使ったことなかったのですが、便利な機能ですね。