Nachrichten aus einem Abo filtern

Auf dieser Seite wird erläutert, wie Sie Pub/Sub-Abos mit Filtern erstellen.

Wenn Sie Nachrichten aus einem Abo mit einem Filter erhalten, erhalten Sie nur die Nachrichten, die dem Filter entsprechen. Der Pub/Sub-Dienst bestätigt automatisch die Nachrichten, die nicht mit dem Filter übereinstimmen. Sie können Nachrichten nach ihren Attributen filtern, aber nicht nach den Daten in der Nachricht.

Ein Thema kann mehrere Abos haben, die jeweils einen anderen Filter haben können.

Wenn Sie beispielsweise ein Thema haben, für das Nachrichten aus verschiedenen Teilen der Welt empfangen werden, können Sie ein Abo so konfigurieren, dass nur Nachrichten gefiltert werden, die nur aus einer bestimmten Region veröffentlicht werden. Bei dieser Konfiguration muss eines der Nachrichtenattribute des Themas die Region der Nachrichtenveröffentlichung enthalten.

Wenn Sie Nachrichten aus einem Abo mit einem Filter erhalten, fallen keine Gebühren für ausgehende Nachrichten für die von Pub/Sub angegebenen Nachrichten an. Für diese Nachrichten fallen Gebühren für die Nachrichtenzustellung und suchbezogene Speichergebühren an.

Abo mit Filter erstellen

Pull- und Push-Abos können Filter enthalten. Alle Abonnenten können Nachrichten von Abos mit Filtern erhalten, einschließlich Abonnenten, die die StreamingPull API verwenden.

Sie können ein Abo mit einem Filter über die Google Cloud Console, die Google Cloud CLI, die Clientbibliotheken oder die Pub/Sub API erstellen.

Console

So erstellen Sie ein Pull-Abo mit einem Filter:

  1. Öffnen Sie in der Google Cloud Console die Seite Abos.

    Zur Seite "Abos"

  2. Klicken Sie auf Abo erstellen.

  3. Geben Sie die Abo-ID ein.

  4. Wählen Sie im Drop-down-Menü ein Thema aus oder erstellen Sie ein Thema. Das Abo erhält Nachrichten aus dem Thema.

  5. Geben Sie im Abschnitt Abo-Filter den Filterausdruck ein.

  6. Klicken Sie auf Erstellen.

So erstellen Sie ein Push-Abo mit einem Filter:

  1. Öffnen Sie in der Google Cloud Console die Seite Abos.

    Zur Seite "Abos"

  2. Klicken Sie auf Abo erstellen.

  3. Geben Sie die Abo-ID ein.

  4. Wählen Sie im Drop-down-Menü ein Thema aus oder erstellen Sie ein Thema. Das Abo erhält Nachrichten aus dem Thema.

  5. Klicken Sie im Bereich Zustellungstyp auf Push.

  6. Geben Sie im Feld Endpunkt-URL die URL des Push-Endpunkts ein.

  7. Geben Sie im Abschnitt Abo-Filter den Filterausdruck ein.

  8. Klicken Sie auf Erstellen.

gcloud

Verwenden Sie zum Erstellen eines Pull-Abos mit einem Filter den Befehl gcloud pubsub subscriptions create mit dem Flag --message-filter:

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

Dabei gilt:

  • SUBSCRIPTION_ID: Die ID des zu erstellenden Abos
  • TOPIC_ID: Die ID des Themas, das an das Abo angehängt werden soll
  • FILTER: Ein Ausdruck in der Filtersyntax

Verwenden Sie zum Erstellen eines Push-Abos mit einem Filter den Befehl gcloud pubsub subscriptions create mit den Flags --push-endpoint und --message-filter:

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

Dabei gilt:

  • SUBSCRIPTION_ID: Die ID des zu erstellenden Abos
  • TOPIC_ID: Die ID des Themas, das an das Abo angehängt werden soll
  • PUSH_ENDPOINT: Die URL des Servers, auf dem der Push-Abonnent ausgeführt wird
  • FILTER: Ein Ausdruck in der Filtersyntax

REST

Wenn Sie ein Abo mit einem Filter erstellen möchten, verwenden Sie die Methode projects.subscriptions.create.

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

Dabei gilt:

  • PROJECT_ID: die Projekt-ID des Projekts, in dem das Abo erstellt werden soll
  • SUBSCRIPTION_ID: Die ID des zu erstellenden Abos

Wenn Sie ein Pull-Abo mit einem Filter erstellen möchten, geben Sie den Filter im Anfragetext an:

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

Dabei gilt:

  • PROJECT_ID: Die Projekt-ID des Projekts mit dem Thema
  • TOPIC_ID: Die ID des Themas, das an das Abo angehängt werden soll
  • FILTER: Ein Ausdruck in der Filtersyntax

Um ein Push-Abo mit einem Filter zu erstellen, geben Sie den Push-Endpunkt und den Filter im Anfragetext an:

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

Dabei gilt:

  • PROJECT_ID: Die Projekt-ID des Projekts mit dem Thema
  • TOPIC_ID: Die ID des Themas, das an das Abo angehängt werden soll
  • PUSH_ENDPOINT: Die URL des Servers, auf dem der Push-Abonnent ausgeführt wird
  • FILTER: Ein Ausdruck in der Filtersyntax

C++

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für C++ in der Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zur 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#

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für C# in der Schnellstart-Anleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu 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

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für Go in der Schnellstart-Anleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu 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

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für Java in der Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu Pub/Sub Java API.

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

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für PHP in der Schnellstart-Anleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu Pub/Sub Node.js API.

/**
 * 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

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für PHP in der Schnellstart-Anleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu Pub/Sub Node.js API.

/**
 * 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

Folgen Sie der Einrichtungsanleitung für PHP unter Schnellstart: Clientbibliotheken verwenden, bevor Sie dieses Beispiel ausprobieren. Weitere Informationen finden Sie in der Referenzdokumentation zur PHP-API von 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

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für Python in der Schnellstart-Anleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu 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

Bevor Sie dieses Beispiel testen, folgen Sie der Einrichtungsanleitung für Ruby in der Schnellstart-Anleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zu 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

Die maximale Länge eines Filters beträgt 256 Byte. Der Filter ist eine unveränderliche Eigenschaft eines Abos. Nachdem Sie ein Abo erstellt haben, können Sie es nicht mehr aktualisieren, um den Filter zu ändern.

Auswirkungen von Filtern auf Backlog-Messwerte

Informationen zum Überwachen des gerade erstellten Abos finden Sie unter Abos mit Filtern beobachten.

Wenn die Filterung aktiviert ist, enthalten die Rückstandmesswerte nur Daten von Nachrichten, die dem Filter entsprechen. Im Folgenden finden Sie eine Liste der Backlog-Messwerte:

  • 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

Weitere Informationen zu diesen Messwerten finden Sie in der Liste der Pub/Sub-Messwerte.

Filter für ein Abo aktualisieren

Sie können den Filter für ein vorhandenes Abo nicht aktualisieren. Führen Sie stattdessen diese Umgehung aus.

  1. Erstellen Sie einen Snapshot des Abos, für das Sie den Filter ändern möchten.

    Weitere Informationen zum Erstellen eines Snapshots mit der Console finden Sie unter Snapshot erstellen.

  2. Erstellen Sie ein neues Abo mit dem neuen Filter.

    Weitere Informationen zum Erstellen eines Abos mit einem Filter finden Sie unter Abo mit Filter erstellen.

  3. Rufen Sie in der Google Cloud Console die Seite Pub/Sub-Abos auf.

    Zu den Abos

  4. Klicken Sie auf das Abo, das Sie gerade erstellt haben.

  5. Klicken Sie auf der Seite mit den Abodetails auf Nachrichten noch einmal abspielen.

  6. Klicken Sie unter Suchen auf Zu einem Snapshot.

  7. Wählen Sie den Snapshot aus, den Sie in Schritt 1 für das ursprüngliche Abo erstellt haben, und klicken Sie dann auf Suchen.

    Während der Umstellung gehen keine Nachrichten verloren.

  8. Ändern Sie alle Abonnenten, damit sie das neue Abo verwenden.

Nachdem Sie diesen Vorgang abgeschlossen haben, können Sie das ursprüngliche Abo löschen.

Syntax zum Erstellen eines Filters

Schreiben Sie zum Filtern von Nachrichten einen Ausdruck, der Attribute verwendet. Sie können einen Ausdruck schreiben, der mit dem Schlüssel oder Wert der Attribute übereinstimmt. Die Kennzeichnung attributes wählt die Attribute in der Nachricht aus.

Wählen Sie beispielsweise die Filter name in der folgenden Tabelle aus:

Filter Beschreibung
attributes:name Nachrichten mit dem Attribut name
NOT attributes:name Nachrichten ohne das Attribut name
attributes.name = "com" Nachrichten mit dem Attribut name und dem Wert com
attributes.name != "com" Nachrichten ohne das Attribut name und den Wert von com
hasPrefix(attributes.name, "co") Nachrichten mit dem Attribut name und einem Wert, der mit co beginnt
NOT hasPrefix(attributes.name, "co") Nachrichten ohne das Attribut name und einem Wert, der mit co beginnt

Vergleichsoperatoren für den Filterausdruck

Sie können Attribute mit den folgenden Vergleichsoperatoren filtern:

  • :
  • =
  • !=

Der Operator : entspricht einem Schlüssel in einer Liste von Attributen.

attributes:KEY

Die Gleichheitsoperatoren stimmen mit Schlüsseln und Werten überein. Der Wert muss ein Stringliteral sein.

attributes.KEY = "VALUE"

Ein Ausdruck mit einem Gleichheitsoperator muss mit einem Schlüssel beginnen und der Gleichheitsoperator muss einen Schlüssel mit einem Wert vergleichen.

  • Gültig: Der Filter vergleicht einen Schlüssel mit einem Wert

    attributes.name = "com"
    
  • Ungültig: Die linke Seite des Filters ist ein Wert.

    "com" = attributes.name
    
  • Ungültig: Der Filter vergleicht zwei Schlüssel

    attributes.name = attributes.website
    

Bei Schlüssel und Wert wird zwischen Groß- und Kleinschreibung unterschieden und sie müssen genau mit dem Attribut übereinstimmen. Wenn ein Schlüssel andere Zeichen als Bindestriche, Unterstriche oder alphanumerische Zeichen enthält, verwenden Sie ein String-Literal.

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

Wenn Sie in einem Filter Backslash, Anführungszeichen und nicht druckbare Zeichen verwenden möchten, müssen Sie die Zeichen in einem Stringliteral mit Escapezeichen versehen. Sie können auch Unicode-, Hexadezimal- und Oktal-Escapesequenzen innerhalb eines Stringliterals verwenden.

  • Valid: Der Filter maskiert Zeichen in einem String-Literal

    attributes:"\u307F\u3093\u306A"
    
  • Ungültig: Der Filter maskiert Zeichen ohne Stringliteral

    attributes:\u307F\u3093\u306A
    

Boolesche Operatoren für den Filterausdruck

Sie können die booleschen Operatoren AND, NOT und OR in einem Filter verwenden. Die Operatoren müssen in Großbuchstaben geschrieben werden. Der folgende Filter ist beispielsweise für Nachrichten mit dem Attribut iana.org/language_tag, aber ohne das Attribut name und den Wert com vorgesehen.

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

Der Operator NOT hat die höchste Priorität. Wenn Sie die Operatoren AND und OR kombinieren möchten, verwenden Sie Klammern und vollständige Ausdrücke.

  • Valid: Die Operatoren AND und OR mit Klammern

    attributes:"iana.org/language_tag" AND (attributes.name = "net" OR attributes.name = "org")
    
  • Ungültig: AND- und OR- Operatoren ohne Klammern

    attributes:"iana.org/language_tag" AND attributes.name = "net" OR attributes.name = "org"
    
  • Ungültig: Die Operatoren AND und OR kombinieren unvollständige Ausdrücke

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

Sie können auch den unären Minusoperator anstelle des NOT-Operators verwenden.

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

Funktionen für den Filterausdruck

Mit der Funktion hasPrefix können Sie nach Attributen mit Werten filtern, die mit einem Teilstring beginnen. hasPrefix ist die einzige unterstützte Funktion in einem Filter.

Der Präfixabgleich wird mit der Funktion hasPrefix unterstützt, allgemeine reguläre Ausdrücke jedoch nicht.

hasPrefix(attributes.KEY, "SUBSTRING")

Ersetzen Sie Folgendes:

  • KEY: der Name des Attributs
  • SUBSTRING: ein Teilstring des Werts