Skip to content

Note

このドキュメントは2026-02-27 03:41PLaMo Translation Modelを使用して自動翻訳されました。

FEP-5bf0: コレクションのソートとフィルタリング機能

概要

本提案では、アクターと同様にコレクションに「streams」プロパティを追加することを許可します。これらのストリームはCollectionView型となり、これはコレクションを並べ替えまたはフィルタリングした状態を表現するために新たに提案されている語彙拡張です。ActivityPubクライアントは、この機能を利用することで、自身でそのようなフィルタリングやソート処理を行うことなく、直接CollectionViewを表示できるようになります。

並び替えやフィルタリングがどのように適用されたかに関するメタデータは、SHACL(Shape Expressions Language)を利用した新たな語彙拡張を用いて記述されます。これにより、制約条件を明確かつ標準化された形式で表現することが可能になります。

背景と必要性

一部のActivityPubクライアントでは、コレクションへのアクセスおよびネストされたアイテムの表示にC2Sプロトコルのみを利用しています。

現状、フィルタリングやソート機能をサポートするためには、これらのクライアントがすべてのページ分割アイテムを取得し、それらを手動で組み立てた後、手作業で並べ替えまたはフィルタリングを行い、再度ページ分割する必要があります。

本提案により、サーバー側でこのような処理をランタイム時あるいは事前に行うことができるようになります。これにより、クライアント側の負荷を軽減することが可能となります。

他のサーバーは自由にコレクションを参照できますが、新たに追加されたプロパティや機能は簡単に無視できるように設計されています。

実装方法

CollectionViewOrderedCollectionを継承し、コレクションのフィルタリングまたはソート済みバージョンを表現するクラスです。同様に、CollectionViewPageOrderedCollectionPageを継承します。

CollectionViewに適用されるフィルタリング方式は、"filter"プロパティによって指定されます。このプロパティは1つ以上のSHACLシェイプと対応付けられます。

語彙セットには、特定のActivityStreamsコレクション内の項目値に含まれるかどうかを示すためのSHACLシェイプも提供されます。

CollectionViewに適用されるソート方法は、「sort」プロパティで指定します。このプロパティは「SortShape」と対応しており、「SortShape」はSHACLのPropertyShapeを拡張したもので、さらに「order」プロパティを追加しています。この「order」プロパティには「昇順」または「降順」を指定できます。

もし「sort」プロパティが存在しない場合、コレクションの元の順序がそのまま適用されます。

使用例

以下に、アクターの受信トレイがすべての投稿アクティビティを返すとともに、サーバー側でフィルタリングされたバージョンをストリームとしてクライアント向けに提供する例を示します。

最初のCollectionViewはLikeアクションのみを抽出して表示します。

2番目のCollectionViewは、返信付きの作成済み記事のみを表示し、複数のフィルタ条件とネストされたプロパティに対するフィルタリング機能を示しています。

3番目のCollectionViewは、ある特定のプロパティ値が特定のActivityStreamsコレクション内に含まれることを示す方法を実演しています。具体例では、アクターAlyssaの同僚によるアクティビティを表示しています(Alyssaはカスタムストリームとして、相互フォロー関係にあるユーザーを「同僚」として分類しています)。

{
  "@context": {
    "@vocab": "https://www.w3.org/ns/activitystreams#",
    "fep": "https://w3id.org/fep#",
    "CollectionView": "fep:CollectionView",
    "viewOf": "fep:viewOf",
    "filter": "fep:filter",
    "sort": "fep:sort",
    "inCollection": "fep:inCollection",
    "SortShape": "fep:SortShape",
    "order": "fep:order",
    "sh": "http://www.w3.org/ns/shacl#",
    "PropertyShape": "sh:PropertyShape",
    "path": "sh:path",
    "hasValue": "sh:hasValue",
    "minCount": "sh:minCount"
  },
  "id": "https://example.social/@alyssa/inbox",
  "type": "OrderedCollection",
  "name": "受信トレイ",
  "totalItems": 1000,
  "first": "https://example.social/@alyssa/inbox/page/1",
  "last": "https://example.social/@alyssa/inbox/page/2",
  "streams": [
    {
      "id": "https://example.social/@alyssa/inbox/likes",
      "type": "CollectionView",
      "name": "Likes",
      "filter": {
        "type": "PropertyShape",
        "path": "type",
        "hasValue": "Like"
      },
      "sort": {
        "type": "SortShape",
        "path": "published",
        "order": "Descending"
      },
      "totalItems": 10,
      "first": "https://example.social/@alyssa/inbox/likes/page/1",
      "last": "https://example.social/@alyssa/inbox/likes/page/1"
    },
    {
      "id": "https://example.social/@alyssa/inbox/posts-with-replies",
      "type": "CollectionView",
      "name": "返信付き投稿",
      "filter": [
        {
          "type": "PropertyShape",
          "path": "type",
          "hasValue": "Create"
        },
        {
          "type": "PropertyShape",
          "path": ["object", "inReplyTo"],
          "minCount": 1
        }
      ],
      "sort": {
        "type": "SortShape",
        "path": "published",
        "order": "Descending"
      },
      "totalItems": 10,
      "first": "https://example.social/@alyssa/inbox/blog-posts/page/1",
      "last": "https://example.social/@alyssa/inbox/blog-posts/page/1",
      "viewOf": "https://example.social/@alyssa/inbox"
    },
    {
      "id": "https://example.social/@alyssa/inbox/notes-by-coworkers",
      "type": "CollectionView",
      "name": "同僚による投稿",
      "filter": {
        "type": "InCollectionShape",
        "path": "actor",
        "hasValue": "https://example.social/@alyssa/friends"
      },
      "sort": {
        "type": "SortShape",
        "path": "createdAt",
        "order": "Ascending"
      },
      "totalItems": 50,
      "first": "https://example.social/@alyssa/inbox/notes-by-coworkers/page/1",
      "last": "https://example.social/@alyssa/inbox/notes-by-coworkers/page/2"
    }
  ]
}

セキュリティ考慮事項

理論上、サーバーは任意の並べ替えやフィルタリングを可能にするテンプレート化されたURLエンドポイントを提供可能です。しかし、これはデータベースインジェクション攻撃などの脆弱性を引き起こす可能性があるため、推奨されません。代わりに、「streams」プロパティを通じて事前に定義されたソート済み/フィルタリング済みCollectionViewのみを公開するようにしてください。

参考文献

  • [ActivityPub] Christine Lemmer Webber, Jessica Tallon, ActivityPub, 2018

著作権情報

法律で認められる範囲内において、本Fediverse Enhancement Proposalの著者らはこの著作物に関するすべての著作権および関連する権利を放棄し、パブリックドメインに寄贈します。