🐡

Drupal: ネストされたフィールドを検索する一例

2023/04/24に公開

概要

以下の記事で、Strapiを用いたネストされたフィールドに対する検索方法を調査しました。

https://zenn.dev/nakamura196/articles/425f987d9cbf9c

今回は同様のことをDrupalで行う方法を調査します。この調査にあたり、以下の記事で、BookとAuthorのコンテンツを登録済みです。

https://zenn.dev/nakamura196/articles/811761bd95fd58

フィルタリングの方法については、以下の記事が参考になりました。

https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module/filtering

検索例

以下に対する検索を行います。

/jsonapi/node/book?

hobby=danceであるauthorを含むbookの検索

  • SHORT

filter[field_authors.field_hobby]=dance

または

filter[field_authors.field_hobby][value]=dance

  • NORMAL

filter[ex1][condition][path]=field_authors.field_hobby&filter[ex1][condition][value]=dance

hobbyにdanを含むauthorを含むbookの検索

  • SHORT

filter[field_authors.field_hobby][operator]=CONTAINS&filter[field_authors.field_hobby][value]=dan

  • NORMAL

filter[ex1][condition][path]=field_authors.field_hobby&filter[ex1][condition][operator]=CONTAINS&filter[ex1][condition][value]=dan

(参考)hobbyがplayまたはsingであるauthorを含むbookの検索

filter[ex1][condition][path]=field_authors.field_hobby&filter[ex1][condition][operator]=IN&filter[ex1][condition][value][1]=sing&filter[ex1][condition][value][2]=play

(参考)Search APIを使う

以下のモジュールを使用することで、複数のコンテンツタイプに対する検索や、フィールド名の指定、ファセットの追加、などができそうです。

https://www.drupal.org/project/jsonapi_search_api

以下の記事で使い方を紹介していますので、参考にしてください。

https://zenn.dev/nakamura196/articles/8d7aa7c33abffc#search-api

indexの作成

例えば、Search APIのindexとして、以下のように設定します。

これにより、以下のURLからもbookの情報が得られます。

/jsonapi/index/book

通常のjsonapi(/jsonapi/node/bookなど)と比較して、metaという項目にcountが含まれることで、検索結果の全数が確認できます。(通常のjsonapiでも追加する方法があるかもしれませんが、調査不足により不明です。)

{
  "jsonapi": {
    "version": "1.0",
    "meta": {
      "links": {
        "self": {
          "href": "http://jsonapi.org/format/1.0/"
        }
      }
    }
  },
  "data": [...],
  "meta": {
    "count": 4
  },
  "links": {
    "self": {
      "href": "https://xxx/jsonapi/index/book"
    }
  }
}

フィルタリング

また、「hobby=danceであるauthorを含むbookの検索」については、先のindex作成において、Property path「field_authors:entity:field_hobby」をMachine name「field_hobby」に割り当てましたので、以下のシンプルなクエリで実行できました。

  • SHORT

filter[field_hobby]=dance

  • NORMAL

filter[ex1][condition][path]=field_hobby&filter[ex1][condition][value]=dance

ファセット

さらに、(本記事執筆時点での不確かな知識において、)Search APIを使用する大きな利点の一つとして、facetsが使用できるようになる点が挙げられます。

{
	"facets": [
		{
			"id": "field_hobby",
			"label": "authors » Content » hobby",
			"path": "field_hobby",
			"terms": [
				{
					"url": "https://xxx/jsonapi/index/book?filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bpath%5D=field_hobby&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Boperator%5D=IN&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bvalue%5D%5B0%5D=dance&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bvalue%5D%5B1%5D=play",
					"values": {
						"value": "play",
						"label": "play",
						"active": false,
						"count": 1
					}
				},
				{
					"url": "https://xxx/jsonapi/index/book?filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bpath%5D=field_hobby&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Boperator%5D=IN&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bvalue%5D%5B0%5D=dance&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bvalue%5D%5B1%5D=sing",
					"values": {
						"value": "sing",
						"label": "sing",
						"active": false,
						"count": 1
					}
				},
				{
					"url": "https://xxx/jsonapi/index/book?filter%5Bfield_hobby%5D=dance",
					"values": {
						"value": "dance",
						"label": "dance",
						"active": true,
						"count": 2
					}
				}
			]
		}
	]
}

まとめ

不正確な情報もあるかもしれませんが、Drupalでのnested構造に対する検索と、JSON:APIとSearch APIの組み合わせについて、参考になりましたら幸いです。

Discussion