Memfilter pesan dari langganan

Halaman ini menjelaskan cara membuat langganan Pub/Sub dengan filter.

Saat menerima pesan dari langganan dengan filter, Anda hanya akan menerima pesan yang cocok dengan filter. Layanan Pub/Sub secara otomatis mengonfirmasi bahwa pesan yang tidak cocok dengan filter. Anda dapat memfilter pesan menurut atribut-nya, tetapi tidak menurut data dalam pesan.

Anda dapat memiliki beberapa langganan yang terpasang ke topik dan setiap langganan dapat memiliki filter yang berbeda.

Misalnya, jika Anda memiliki topik yang menerima berita dari berbagai bagian dunia, Anda dapat mengonfigurasi langganan untuk memfilter berita yang hanya dipublikasikan dari wilayah tertentu. Untuk konfigurasi ini, Anda harus memastikan bahwa salah satu atribut pesan topik menunjukkan wilayah publikasi berita.

Saat menerima pesan dari langganan dengan filter, Anda tidak dikenai biaya pesan keluar untuk pesan yang otomatis dikonfirmasi oleh Pub/Sub. Anda akan dikenai biaya pengiriman pesan dan biaya penyimpanan terkait penelusuran untuk pesan ini.

Membuat langganan dengan filter

Langganan pull dan push dapat memiliki filter. Semua pelanggan dapat menerima pesan dari langganan dengan filter, termasuk pelanggan yang menggunakan StreamingPull API.

Anda dapat membuat langganan dengan filter menggunakan konsol Google Cloud, Google Cloud CLI, library klien, atau Pub/Sub API.

Konsol

Untuk membuat langganan pull dengan filter, ikuti langkah-langkah berikut:

  1. Di konsol Google Cloud, buka halaman Langganan.

    Buka halaman Langganan

  2. Klik Buat langganan.

  3. Masukkan ID Langganan.

  4. Pilih atau buat topik dari menu drop-down. Langganan menerima pesan dari topik.

  5. Di bagian Filter subscription, masukkan ekspresi filter.

  6. Klik Create.

Untuk membuat langganan push dengan filter, ikuti langkah-langkah berikut:

  1. Di konsol Google Cloud, buka halaman Langganan.

    Buka halaman Langganan

  2. Klik Buat langganan.

  3. Masukkan ID Langganan.

  4. Pilih atau buat topik dari menu drop-down. Langganan menerima pesan dari topik.

  5. Di bagian Jenis pengiriman, klik Push.

  6. Di kolom Endpoint URL, masukkan URL endpoint push.

  7. Di bagian Filter subscription, masukkan ekspresi filter.

  8. Klik Create.

gcloud

Untuk membuat langganan pull dengan filter, gunakan perintah gcloud pubsub subscriptions create dengan flag --message-filter:

gcloud pubsub subscriptions create SUBSCRIPTION_ID \
  --topic=TOPIC_ID \
  --message-filter='FILTER'

Ganti kode berikut:

  • SUBSCRIPTION_ID: ID langganan yang akan dibuat
  • TOPIC_ID: ID topik yang akan dilampirkan ke langganan
  • FILTER: ekspresi dalam sintaksis pemfilteran

Untuk membuat langganan push dengan filter, gunakan perintah gcloud pubsub subscriptions create dengan flag --push-endpoint dan --message-filter:

gcloud pubsub subscriptions create SUBSCRIPTION_ID \
  --topic=TOPIC_ID \
  --push-endpoint=PUSH_ENDPOINT \
  --message-filter='FILTER'

Ganti kode berikut:

  • SUBSCRIPTION_ID: ID langganan yang akan dibuat
  • TOPIC_ID: ID topik yang akan dilampirkan ke langganan
  • PUSH_ENDPOINT: URL server tempat subscriber push berjalan
  • FILTER: ekspresi dalam sintaksis pemfilteran

REST

Untuk membuat langganan dengan filter, gunakan metode projects.subscriptions.create.

PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID
Authorization: Bearer $(gcloud auth print-access-token)

Ganti kode berikut:

  • PROJECT_ID: project ID untuk project tempat langganan akan dibuat
  • SUBSCRIPTION_ID: ID langganan yang akan dibuat

Untuk membuat langganan pull dengan filter, tentukan filter dalam isi permintaan:

{
  "topic": "projects/PROJECT_ID/topics/TOPIC_ID",
  "filter": "FILTER"
}

Ganti kode berikut:

  • PROJECT_ID: project ID untuk project dengan topik
  • TOPIC_ID: ID topik yang akan dilampirkan ke langganan
  • FILTER: ekspresi dalam sintaksis pemfilteran

Untuk membuat langganan push dengan filter, tentukan endpoint push dan filter dalam isi permintaan:

{
  "topic": "projects/PROJECT_ID/topics/TOPIC_ID",
  "pushConfig": {
    "pushEndpoint": "PUSH_ENDPOINT"
  },
  "filter": "FILTER"
}

Ganti kode berikut:

  • PROJECT_ID: project ID untuk project dengan topik
  • TOPIC_ID: ID topik yang akan dilampirkan ke langganan
  • PUSH_ENDPOINT: URL server tempat subscriber push berjalan
  • FILTER: ekspresi dalam sintaksis pemfilteran

C++

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan C++ di Panduan Memulai: Menggunakan Library Klien. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Pub/Sub C++ API.

namespace pubsub = ::google::cloud::pubsub;
namespace pubsub_admin = ::google::cloud::pubsub_admin;
[](pubsub_admin::SubscriptionAdminClient client,
   std::string const& project_id, std::string topic_id,
   std::string subscription_id) {
  google::pubsub::v1::Subscription request;
  request.set_name(
      pubsub::Subscription(project_id, std::move(subscription_id))
          .FullName());
  request.set_topic(
      pubsub::Topic(project_id, std::move(topic_id)).FullName());
  request.set_filter(R"""(attributes.is-even = "false")""");
  auto sub = client.CreateSubscription(request);
  if (sub.status().code() == google::cloud::StatusCode::kAlreadyExists) {
    std::cout << "The subscription already exists\n";
    return;
  }
  if (!sub) throw std::move(sub).status();

  std::cout << "The subscription was successfully created: "
            << sub->DebugString() << "\n";
}

C#

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan C# di Panduan Memulai: Menggunakan Library Klien. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Pub/Sub C# API.


using Google.Cloud.PubSub.V1;
using Grpc.Core;

public class CreateSubscriptionWithFilteringSample
{
    public Subscription CreateSubscriptionWithFiltering(string projectId, string topicId, string subscriptionId, string filter)
    {
        SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create();
        TopicName topicName = TopicName.FromProjectTopic(projectId, topicId);
        SubscriptionName subscriptionName = SubscriptionName.FromProjectSubscription(projectId, subscriptionId);
        Subscription subscription = null;

        var subscriptionRequest = new Subscription
        {
            SubscriptionName = subscriptionName,
            TopicAsTopicName = topicName,
            Filter = filter
        };

        try
        {
            subscription = subscriber.CreateSubscription(subscriptionRequest);
        }
        catch (RpcException e) when (e.Status.StatusCode == StatusCode.AlreadyExists)
        {
            // Already exists.  That's fine.
        }
        return subscription;
    }
}

Go

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di Panduan Memulai: Menggunakan Library Klien. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Pub/Sub Go API.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsub"
)

func createWithFilter(w io.Writer, projectID, subID, filter string, topic *pubsub.Topic) error {
	// Receive messages with attribute key "author" and value "unknown".
	// projectID := "my-project-id"
	// subID := "my-sub"
	// filter := "attributes.author=\"unknown\""
	// topic of type https://godoc.org/cloud.google.com/go/pubsub#Topic
	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %w", err)
	}
	defer client.Close()

	sub, err := client.CreateSubscription(ctx, subID, pubsub.SubscriptionConfig{
		Topic:  topic,
		Filter: filter,
	})
	if err != nil {
		return fmt.Errorf("CreateSubscription: %w", err)
	}
	fmt.Fprintf(w, "Created subscription with filter: %v\n", sub)
	return nil
}

Java

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di Panduan Memulai: Menggunakan Library Klien. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Java API Pub/Sub.

import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.ProjectTopicName;
import com.google.pubsub.v1.Subscription;
import java.io.IOException;

public class CreateSubscriptionWithFiltering {
  public static void main(String... args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String topicId = "your-topic-id";
    String subscriptionId = "your-subscription-id";
    String filter = "attributes.author=\"unknown\"";

    createSubscriptionWithFilteringExample(projectId, topicId, subscriptionId, filter);
  }

  public static void createSubscriptionWithFilteringExample(
      String projectId, String topicId, String subscriptionId, String filter) throws IOException {
    try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {

      ProjectTopicName topicName = ProjectTopicName.of(projectId, topicId);
      ProjectSubscriptionName subscriptionName =
          ProjectSubscriptionName.of(projectId, subscriptionId);

      Subscription subscription =
          subscriptionAdminClient.createSubscription(
              Subscription.newBuilder()
                  .setName(subscriptionName.toString())
                  .setTopic(topicName.toString())
                  // Receive messages with attribute key "author" and value "unknown".
                  .setFilter(filter)
                  .build());

      System.out.println(
          "Created a subscription with filtering enabled: " + subscription.getAllFields());
    }
  }
}

Node.js

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Node.js di Panduan Memulai: Menggunakan Library Klien. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Node.js Pub/Sub.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';
// const filterString = 'YOUR_FILTER_STRING';   // e.g. 'attributes.author="unknown"'

// Imports the Google Cloud client library
const {PubSub} = require('@google-cloud/pubsub');

// Creates a client; cache this for further use
const pubSubClient = new PubSub();

async function createSubscriptionWithFilter(
  topicNameOrId,
  subscriptionNameOrId,
  filterString
) {
  // Creates a new subscription
  await pubSubClient
    .topic(topicNameOrId)
    .createSubscription(subscriptionNameOrId, {
      filter: filterString,
    });
  console.log(
    `Created subscription ${subscriptionNameOrId} with filter ${filterString}.`
  );
}

Node.js

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Node.js di Panduan Memulai: Menggunakan Library Klien. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Node.js Pub/Sub.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';
// const filterString = 'YOUR_FILTER_STRING';   // e.g. 'attributes.author="unknown"'

// Imports the Google Cloud client library
import {PubSub} from '@google-cloud/pubsub';

// Creates a client; cache this for further use
const pubSubClient = new PubSub();

async function createSubscriptionWithFilter(
  topicNameOrId: string,
  subscriptionNameOrId: string,
  filterString: string
) {
  // Creates a new subscription
  await pubSubClient
    .topic(topicNameOrId)
    .createSubscription(subscriptionNameOrId, {
      filter: filterString,
    });
  console.log(
    `Created subscription ${subscriptionNameOrId} with filter ${filterString}.`
  );
}

PHP

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan PHP di Panduan Memulai: Menggunakan Library Klien. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API PHP Pub/Sub.

use Google\Cloud\PubSub\PubSubClient;

/**
 * Creates a Pub/Sub subscription.
 *
 * @param string $projectId  The Google project ID.
 * @param string $topicName  The Pub/Sub topic name.
 * @param string $subscriptionName  The Pub/Sub subscription name.
 * @param string $filter  The Pub/Sub subscription filter.
 */
function create_subscription_with_filter(
    string $projectId,
    string $topicName,
    string $subscriptionName,
    string $filter
): void {
    $pubsub = new PubSubClient([
        'projectId' => $projectId,
    ]);
    $topic = $pubsub->topic($topicName);
    $subscription = $topic->subscription($subscriptionName);

    $subscription->create(['filter' => $filter]);

    printf('Subscription created: %s' . PHP_EOL, $subscription->name());
    printf('Subscription info: %s' . PHP_EOL, json_encode($subscription->info()));
}

Python

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di Panduan Memulai: Menggunakan Library Klien. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Pub/Sub Python API.

from google.cloud import pubsub_v1

# TODO(developer): Choose an existing topic.
# project_id = "your-project-id"
# topic_id = "your-topic-id"
# subscription_id = "your-subscription-id"
# filter = "attributes.author=\"unknown\""

publisher = pubsub_v1.PublisherClient()
subscriber = pubsub_v1.SubscriberClient()
topic_path = publisher.topic_path(project_id, topic_id)
subscription_path = subscriber.subscription_path(project_id, subscription_id)

with subscriber:
    subscription = subscriber.create_subscription(
        request={"name": subscription_path, "topic": topic_path, "filter": filter}
    )
    print(f"Created subscription with filtering enabled: {subscription}")

Ruby

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Ruby di Panduan Memulai: Menggunakan Library Klien. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Pub/Sub Ruby API.

require "google/cloud/pubsub"

# Shows how to create a new subscription with filter for a given topic
class PubsubCreateSubscriptionWithFilter
  def create_subscription_with_filter project_id:, topic_id:, subscription_id:, filter:
    pubsub = Google::Cloud::Pubsub.new project_id: project_id
    topic = pubsub.topic topic_id
    subscription = topic.subscribe subscription_id, filter: filter
    puts "Created subscription with filtering enabled: #{subscription_id}"
  end

  def self.run
    # TODO(developer): Replace these variables before running the sample.
    project_id = "your-project-id"
    topic_id = "your-topic-id"
    subscription_id = "id-for-new-subcription"
    filter = "attributes.author=\"unknown\""
    PubsubCreateSubscriptionWithFilter.new.create_subscription_with_filter project_id: project_id,
                                                                           topic_id: topic_id,
                                                                           subscription_id: subscription_id,
                                                                           filter: filter
  end
end

if $PROGRAM_NAME == __FILE__
  PubsubCreateSubscriptionWithFilter.run
end

Panjang maksimum filter adalah 256 byte. Filter adalah properti langganan yang tidak dapat diubah. Setelah membuat langganan, Anda tidak dapat memperbarui langganan untuk mengubah filter.

Pengaruh filter terhadap metrik backlog

Untuk memantau langganan yang baru saja Anda buat, lihat Memantau langganan dengan filter.

Jika Anda mengaktifkan pemfilteran, metrik backlog hanya akan menyertakan data dari pesan yang cocok dengan filter. Berikut adalah daftar metrik backlog:

  • subscription/backlog_bytes
  • subscription/unacked_bytes_by_region
  • subscription/num_undelivered_messages
  • subscription/num_unacked_messages_by_region
  • subscription/oldest_unacked_message_age
  • subscription/oldest_unacked_message_age_by_region
  • topic/unacked_bytes_by_region
  • topic/num_unacked_messages_by_region
  • topic/oldest_unacked_messages_age_by_region

Untuk mempelajari metrik ini lebih lanjut, lihat daftar metrik Pub/Sub.

Memperbarui filter untuk langganan

Anda tidak dapat memperbarui filter untuk langganan yang sudah ada. Sebagai gantinya, ikuti solusi ini.

  1. Ambil snapshot langganan yang filternya ingin Anda ubah.

    Untuk mengetahui lebih lanjut cara mengambil snapshot menggunakan konsol, lihat Membuat snapshot.

  2. Buat langganan baru dengan filter baru.

    Untuk mengetahui lebih lanjut cara membuat langganan dengan filter, lihat Membuat langganan dengan filter.

  3. Di konsol Google Cloud, buka halaman Langganan Pub/Sub.

    Buka langganan

  4. Klik langganan yang baru saja Anda buat.

  5. Di halaman detail langganan, klik Putar ulang pesan.

  6. Untuk Cari, klik Ke snapshot.

  7. Pilih snapshot yang Anda buat untuk langganan asli di langkah 1, lalu klik Seek.

    Anda tidak akan kehilangan pesan apa pun selama transisi.

  8. Ubah pelanggan agar menggunakan langganan baru.

Setelah menyelesaikan prosedur ini, Anda dapat melanjutkan dan menghapus langganan asli.

Sintaksis untuk membuat filter

Untuk memfilter pesan, tulis ekspresi yang beroperasi pada atribut. Anda dapat menulis ekspresi yang cocok dengan kunci atau nilai atribut. ID attributes memilih atribut dalam pesan.

Misalnya, filter dalam tabel berikut memilih atribut name:

Filter Deskripsi
attributes:name Pesan dengan atribut name
NOT attributes:name Pesan tanpa atribut name
attributes.name = "com" Pesan dengan atribut name dan nilai com
attributes.name != "com" Pesan tanpa atribut name dan nilai com
hasPrefix(attributes.name, "co") Pesan dengan atribut name dan nilai yang diawali dengan co
NOT hasPrefix(attributes.name, "co") Pesan tanpa atribut name dan nilai yang dimulai dengan co

Operator perbandingan untuk ekspresi filter

Anda dapat memfilter atribut dengan operator perbandingan berikut:

  • :
  • =
  • !=

Operator : mencocokkan kunci dalam daftar atribut.

attributes:KEY

Operator persamaan mencocokkan kunci dan nilai. Nilai harus berupa literal string.

attributes.KEY = "VALUE"

Ekspresi dengan operator persamaan harus diawali dengan kunci, dan operator persamaan harus membandingkan kunci dan nilai.

  • Valid: Filter membandingkan kunci dan nilai

    attributes.name = "com"
    
  • Tidak valid: Sisi kiri filter adalah nilai

    "com" = attributes.name
    
  • Tidak valid: Filter membandingkan dua kunci

    attributes.name = attributes.website
    

Kunci dan nilai peka huruf besar/kecil dan harus sama persis dengan atribut. Jika kunci berisi karakter selain tanda hubung, garis bawah, atau karakter alfanumerik, gunakan literal string.

attributes."iana.org/language_tag" = "en"

Untuk menggunakan garis miring terbalik, tanda petik, dan karakter non-cetak dalam filter, escape karakter dalam literal string. Anda juga dapat menggunakan urutan escape Unicode, heksadesimal, dan oktal dalam literal string.

  • Valid: Filter meng-escape karakter dalam literal string

    attributes:"\u307F\u3093\u306A"
    
  • Tidak valid: Filter meng-escape karakter tanpa literal string

    attributes:\u307F\u3093\u306A
    

Operator Boolean untuk ekspresi filter

Anda dapat menggunakan operator logika boolean AND, NOT, dan OR dalam filter. Operator harus dalam huruf besar. Misalnya, filter berikut adalah untuk pesan dengan atribut iana.org/language_tag, tetapi tanpa atribut name dan nilai com.

attributes:"iana.org/language_tag" AND NOT attributes.name = "com"

Operator NOT memiliki prioritas tertinggi. Untuk menggabungkan operator AND dan OR, gunakan tanda kurung dan ekspresi lengkap.

  • Valid: Operator AND dan OR dengan tanda kurung

    attributes:"iana.org/language_tag" AND (attributes.name = "net" OR attributes.name = "org")
    
  • Tidak valid: Operator AND dan OR tanpa tanda kurung

    attributes:"iana.org/language_tag" AND attributes.name = "net" OR attributes.name = "org"
    
  • Tidak valid: Operator AND dan OR menggabungkan ekspresi yang tidak lengkap

    attributes.name = "com" AND ("net" OR "org")
    

Anda juga dapat menggunakan operator minus unary, bukan operator NOT.

attributes.name = "com" AND -attributes:"iana.org/language_tag"

Fungsi untuk ekspresi filter

Anda dapat menggunakan fungsi hasPrefix untuk memfilter atribut dengan nilai yang dimulai dengan substring. hasPrefix adalah satu-satunya fungsi yang didukung dalam filter.

Meskipun pencocokan awalan didukung dengan fungsi hasPrefix, ekspresi reguler umum tidak didukung.

hasPrefix(attributes.KEY, "SUBSTRING")

Ganti kode berikut:

  • KEY: nama atribut
  • SUBSTRING: substring nilai