検索APIの基本
Liferay DXP 2025.Q4+/Portal 2026.Q1+で一般提供開始
Liferayの検索ページからコンテンツを検索できますが、/searchAPIエンドポイントを使うこともできます。 Liferay をローカルで実行している場合は、ログインした状態で http://localhost:8080/o/api?endpoint=http://localhost:8080/o/search/v1.0/openapi.json にアクセスして API を調べることができます。
付属のコマンドを使用して、サンプルコンテンツを生成および検索してください。 以下のコマンドは基本認証で動作し、Liferay がローカルで http://localhost:8080 で実行されており、管理者としてメール test@liferay.com とパスワード learn を使用して認証されていることを前提としています。
ブログ記事を生成するには、以下のコマンドを実行してください。
curl \
-H "Content-Type: application/json" \
-X POST \
"http://localhost:8080/o/headless-delivery/v1.0/sites/L_GUEST/blog-postings" \
--data-raw '{"articleBody": "Foo", "headline": "Able"}' \
-u "test@liferay.com:learn"
LiferayバンドルまたはDockerコンテナのデフォルトサイトは、外部参照コード(ERC) L_GUESTを使用します。 インスタンスに L_GUEST ERC を持つサイトがない場合は、上記の呼び出しで、対象とするサイト ID または ERC に置き換えてください。
/search API には、検索結果ページを返すための GET エンドポイントと POST エンドポイントが含まれています。 ここでは両方の例を示し、解説する。
シンプルなクエリ
キーワード able に対するシンプルな GET クエリは次のとおりです。
curl \
"http://localhost:8080/o/search/v1.0/search?search=able" \
--user "test@liferay.com:learn"
キーワード able に対するシンプルな POST クエリは次のとおりです。
curl \
-H "Content-Type: application/json" \
-X POST \
"http://localhost:8080/o/search/v1.0/search?search=able" \
-d "{}" \
-u "test@liferay.com:learn"
どちらの場合も、レスポンスにはブログ記事に関する情報を含む検索結果が返されます。
{
"items" : [ {
"dateModified" : "2023-07-20T17:15:32Z",
"description" : "Foo",
"itemURL" : "http://localhost:8080/o/headless-delivery/v1.0/blog-postings/35384",
"score" : 318.95966,
"title" : "Able"
} ],
"lastPage" : 1,
"page" : 1,
"pageSize" : 20,
"totalCount" : 1
}
埋め込みアイテムを含むシンプルなクエリ
検索結果だけでなく、返されたエンティティのフィールドをその独自の API スキーマに従って返すには、 nestedField パラメーターを embedded に設定します。 これはGET検索とPOST検索の両方に適用されます。 例えば、キーワード と able に対するこの POST クエリは、埋め込みアイテムも要求します。
curl \
-H "Content-Type: application/json" \
-X POST \
"http://localhost:8080/o/search/v1.0/search?nestedFields=embedded&&search=able" \
-d "{}" \
-u "test@liferay.com:learn"
レスポンスには、ブログ記事に関するより詳細な情報が含まれています。
{
"items" : [ {
"dateModified" : "2023-07-20T17:15:32Z",
"description" : "Foo",
"embedded" : {
"actions": {
"get-rendered-content-by-display-page": {
"method": "GET",
"href": "http://localhost:8080/o/headless-delivery/v1.0/blog-postings/38975/rendered-content-by-display-page/{displayPageKey}"
},
"get": {
"method": "GET",
"href": "http://localhost:8080/o/headless-delivery/v1.0/blog-postings/38975"
},
"replace": {
"method": "PUT",
"href": "http://localhost:8080/o/headless-delivery/v1.0/blog-postings/38975"
},
"update": {
"method": "PATCH",
"href": "http://localhost:8080/o/headless-delivery/v1.0/blog-postings/38975"
},
"delete": {
"method": "DELETE",
"href": "http://localhost:8080/o/headless-delivery/v1.0/blog-postings/38975"
}
},
"alternativeHeadline" : "",
"articleBody" : "Foo",
"creator" : {
"additionalName" : "",
"contentType" : "UserAccount",
"familyName" : "Test",
"givenName" : "Test",
"id" : 20123,
"name" : "Test Test"
},
"customFields" : [ ],
"dateCreated" : "2023-07-20T17:15:32Z",
"dateModified" : "2023-07-20T17:15:32Z",
"datePublished" : "2023-07-20T17:15:00Z",
"description" : "Foo",
"encodingFormat" : "text/html",
"externalReferenceCode" : "f73109ce-8db6-36e3-f2c7-4505c6454ed8",
"friendlyUrlPath" : "able",
"headline" : "Able",
"id" : 35384,
"keywords" : [ ],
"numberOfComments" : 0,
"relatedContents" : [ ],
"renderedContents" : [ ],
"siteId" : 20119,
"taxonomyCategoryBriefs" : [ ]
},
"itemURL" : "http://localhost:8080/o/headless-delivery/v1.0/blog-postings/35384",
"score" : 318.95966,
"title" : "Able"
} ],
"lastPage" : 1,
"page" : 1,
"pageSize" : 20,
"totalCount" : 1
}
サポートされているパラメータとリクエストボディのプロパティを使用することで、より複雑なリクエストを作成できます。
検索パラメータ
クエリパラメータを使用することで、結果をさらに細かく制御できます。
| パラメーター | メモ | メソッド |
|---|---|---|
entryClassNames | 検索対象の エントリクラス名 をカンマで区切ったリスト。 デフォルトでは、すべての検索対象タイプが対象となります。 | GET POST |
fields | fields パラメータは、レスポンス内の各要素において、特定のフィールドのみを列挙するように要求します。 | GET POST |
nestedFields | ネストされたデータを取得するために、 に埋め込まれた をサポートします。 | GET POST |
restrictFields | 指定されたフィールドを返対象から除外します。 | GET POST |
filter | 複数の分野を横断してフィルタリングします。 サポートされているフィールドは、以下の表に記載されています。 より高度なフィルタリングオプションを利用するには、検索ブループリント(DXPサブスクリプション)を使用してください。 | GET POST |
page | 戻るページを指定してください。 | GET POST |
pageSize | 1ページあたりの表示件数を指定してください。 | GET POST |
scope | 検索対象となるサイトのリスト(IDまたはERCで指定)を指定してください。 同じリクエスト内でIDとERCを混在させることができます。 | GET POST |
search | キーワードで検索してください。 | GET POST |
sort | 昇順または降順で並べ替えます。 サポートされているフィールドは、以下の表に記載されています。 | GET POST |
blueprintExternalReferenceCode | 検索要求をカスタマイズするには、 検索ブループリント を指定します。 POSTリクエストでは、代わりに リクエスト属性を使用する必要があります。 | GET |
emptySearch | 検索 パラメータに検索キーワードが入力されていない場合に結果を返すには、これをtrueに設定します。 | GET |
検索ブループリント は、検索ページにソート設定を追加することもできます。 ブループリントを追加したソートと ソートパラメータを両方使用する場合は、ソートパラメータとの相互作用を理解しておいてください。
詳細については、 APIクエリパラメータ を参照してください。
フィルターフィールド
ヘッドレスエンティティのレスポンスにこれらのフィールドが含まれている場合、これらのフィールドでフィルタリングやソートを行うことができます。
| APIフィールド | 対応する検索インデックスフィールド | パラメーター |
|---|---|---|
creatorId | userId | 絞り込み |
folderId | folderId | 絞り込み |
groupIds | groupId | 絞り込み |
objectDefinitionId | objectDefinitionId | 絞り込み |
objectDefinitionExternalReferenceCode | objectDefinitionExternalReferenceCode | 絞り込み |
objectFolderExternalReferenceCode | objectFolderExternalReferenceCode | 絞り込み |
status | status | 絞り込み |
taxonomyCategoryIds | assetCategoryIds | 絞り込み |
dateCreated | createDatecreateDate_sortable | フィルター ソート |
dateDisplay | 日付表示日付ソート可能表示 | フィルター ソート |
dateExpiration | 有効期限有効期限ソート可能 | フィルター ソート |
dateModified | 変更済み変更済み_ソート可能 | フィルター ソート |
datePublish | publishDatepublishDate_sortable | フィルター ソート |
dateReview | レビュー日レビュー日(ソート可能) | フィルター ソート |
extension | extension | 絞り込み |
keywords | assetTagNames.lowercase | フィルター ソート |
scopeGroupId | scopeGroupId | 絞り込み |
title | localized_title_[locale].keyword_lowercase | フィルター ソート |
この数値は最新の四半期報告書に基づいています。 フィールドの利用可否はバージョンやエンティティによって異なる場合があります。ご使用の環境のAPIスキーマ内で、特定のフィールドのサポート状況をご確認ください。
- 便宜上、対応する検索インデックスフィールド名が表示されます。 バージョン間で予告なく変更される場合があります。 インデックス付きフィールドの詳細については、 インデックス付きフィールドの探索 を参照してください。
- ヘッドレス API フィールド
キーワードは、エンティティの タグ名 を参照します。
ステータスによるフィルタリング
DXP 2025.Q3+
デフォルトでは、検索時に承認済みのアイテムのみが返されます(つまり、ステータスが 0 のアイテム)。 ステータスフィールドでフィルタリングすることで、他のワークフローステータスを持つアイテムを取得できます。 例えば、承認済みアイテムと保留中アイテムの両方を返すフィルター値は、 status eq 0 or status eq 1 です。
ウェブコンテンツ記事をステータスでフィルタリングすることはできません。 検索によって返されるコンテンツの ヘッダー バージョンのみが保証される組み込みフィルターがあります。 つまり、検索できるのは最新の承認済みコンテンツのみということになります。
検索リクエスト本文
GET検索ではリクエストボディは含まれません。 POST検索では、空のリクエストも許可されています(例:リクエストボディとして {} を指定)。ただし、レスポンスに影響を与えるためのプロパティが2つあります。
| プロパティ | 説明 |
|---|---|
attributes | 利用可能な検索コンテキスト属性を設定して、検索ブループリントを構成するか、空の検索を有効にします。 詳細については、 利用可能な検索リクエスト属性 を参照してください。 |
facetConfiguration | レスポンスにファセットを含めるように、ファセット設定を行います。 リクエストにファセット構成を追加するを参照してください。 |
検索リクエストに属性を追加する
ブループリントを使用して検索するには、次のリクエストボディ構文を使用します。
{
"attributes": {
"search.experiences.blueprint.external.reference.code": ""
}
}
カスタム検索リクエスト属性
APIリクエストにカスタム属性を追加し、 検索ブループリントでその値を使用できます。 カスタム属性を使用すると、検索リクエストは動的なコンテキストデータを受け取り、それをブループリントに渡すことができます。 ブループリントでは、値でフィルタリングしたり、クエリの設定に使用したり、 条件 に追加したりすることができます。 これにより、コンテキストデータを使用してパーソナライズされた検索体験を作成することが可能になります。
カスタム属性の接頭辞として search.experiences を付けます。 この例では、 freshnessInteger とその値を検索リクエストに追加します。
{
"attributes": {
"search.experiences.freshnessInteger": 30
}
}
属性をブループリント内の パラメーターとして宣言し、その型を指定します。
{
"parameters": {
"search.experiences.freshnessInteger": {
"type": "Integer"
}
}
}
要素 内で値 を使用します。 例えば、 範囲 クエリと createDate フィールドを使用して、過去 30 日間に公開されたコンテンツをクエリします。
"query": {
"range": {
"createDate": {
"gte": "now-"${search.experiences.freshnessInteger}d/d",
"lte": "now/d"
}
}
}
利用可能な検索リクエスト属性
これらの属性をリクエストに設定することができる:
| プロパティ | 説明 |
|---|---|
search.empty.search | リクエストから検索パラメータ が省略された場合でも結果を返すには、これを true に設定します。 |
DXPのみsearch.experiences.blueprint.external.reference.code | (推奨)検索クエリと構成を制御するために、 検索ブループリント を設定します。 |
DXPのみsearch.experiences.blueprint.id | 検索クエリと構成を制御するには、 検索ブループリント を設定します。 |
DXPのみsearch.experiences.ip.address | 自動的に設定されます。 異なる場所をシミュレートするために、地理位置情報 が設定されたブループリント をテストする場合のみ、これを使用してください。 |
DXPのみsearch.experiences.scope.group.id | ブループリントで、これを必要とする 要素 を使用する場合は、これを設定します。検索を現在のサイトに限定する、ユーザーセグメントのカテゴリ内のコンテンツをブーストする、またはステージング対応。 |
DXPのみsearch.experiences.* | カスタム属性を使用することで、ブループリントを基盤とするヘッドレス検索リクエストに動的なデータを渡すことができます。 これらの属性の前に search.experiences. を付けます。 そして、それらをブループリントの パラメータ設定で宣言します。 |
リクエストにファセット設定を追加する
ファセット設定を使用して検索するには、次のリクエストボディ構文を使用します。
{
"facetConfigurations": [
{
"aggregationName": "",
"attributes": {},
"frequencyThreshold": "",
"maxTerms": "",
"name": "",
"values": []
}
]
}
ファセット構成には、いくつかのプロパティがあります。
| プロパティ | 説明 |
|---|---|
aggregationName | 集計に固有の名前を選択してください。 これは、同じタイプのインスタンス(つまり、同じ 名前 プロパティを持つインスタンス)を区別するために必要です。 |
attributes | 一部のファセットには追加の属性が必要です。フィールド: カスタム、 日付範囲、および ネストされた ファセットには、結果を集計するフィールドを設定するための フィールド と呼ばれる文字列属性が必要です。フォーマットと範囲を指定します: 日付範囲ファセットには、日付の書式を指定する書式文字列 (たとえばyyyyMMddHHmmss) と、範囲を指定する範囲オブジェクト配列も必要です。filterField、 filterValue、および path: ネストされた ファセットには、 filterfield String、 filtervalue String、および パス 文字列。vocabularyIds: 語彙 ファセットには、 vocabularyIds の文字列配列が必要です。 |
frequencyThreshold | ファセット用語リストに用語が表示されるために必要な最小頻度を設定します。 |
maxTerms | ファセットに一致する用語がいくつ見つかったかに関わらず、表示するファセット用語の最大数を設定します。 |
name | ファセットの種類を設定します:カテゴリカスタム日付範囲フォルダーネストサイトタグタイプ語彙ユーザー |
values | 値を選択して結果を後処理でフィルタリングします。 これは、ファセットウィジェットでファセット用語をクリックするのと似ています。 |
カスタム ファセットは、トップレベルのフィールドを認識します。 オブジェクトと Web コンテンツ構造フィールドはネストされたフィールドとしてインデックス化されるため、これらのエンティティには ネストされた ファセットを選択する必要があります。
例えば、 日付範囲 ファセットの 範囲 属性は次のようになります。
{
"ranges": [
{
"label": "range-1",
"range": "[20220411085757 TO 20230413075757]"
},
{
"label": "range-2",
"range": "[20230409085757 TO 20230413075757]"
}
]
}
レスポンスにおける集計と検索ファセット
GET検索ではファセットは返されません。 POST検索の場合、APIレスポンスで 集計 と 検索ファセット を確認できます。 集計結果を見るには、
リクエストに ファセット構成 を追加すると、検索ファセットが返されます。 例えば、このリクエストボディはタグファセットを要求しています。
{
"facetConfigurations": [
{
"name": "tag"
}
]
}
レスポンスでは、返された検索ファセットは次のようになります。
"searchFacets": {
"tag": [
{
"displayName": "business",
"term": "business",
"frequency": 26
},
{
"displayName": "fun",
"term": "fun",
"frequency": 1
}
]
}
検索APIへのゲストアクセスを有効にする
ゲストが API にアクセスできるようにするには、 次のように新しいサービス アクセス ポリシー を作成します。
| 項目 | エントリ |
|---|---|
| 名前 | 検索 |
| 有効 | チェック済み |
| デフォルト | チェック済み |
| タイトル | 検索APIへの一般アクセス |
| サービスクラス名 | com.liferay.portal.search.rest.internal.resource.v1_0.SearchResultResourceImpl |
| メッソド名 | [postSearchPage OR getSearchPage] |