๊ตฌ๋…์—์„œ ๋ฉ”์‹œ์ง€ ํ•„ํ„ฐ๋ง

์ด ํŽ˜์ด์ง€์—์„œ๋Š” ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Pub/Sub ๊ตฌ๋…์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ๋…์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•  ๋•Œ๋Š” ํ•„ํ„ฐ์™€ ์ผ์น˜ํ•˜๋Š” ๋ฉ”์‹œ์ง€๋งŒ ์ˆ˜์‹ ๋ฉ๋‹ˆ๋‹ค. Pub/Sub ์„œ๋น„์Šค๋Š” ํ•„ํ„ฐ์™€ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ž๋™์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์‹œ์ง€์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ ์†์„ฑ์— ๋”ฐ๋ผ ๋ฉ”์‹œ์ง€๋ฅผ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์ œ์— ์—ฌ๋Ÿฌ ๊ตฌ๋…์„ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๊ณ  ๊ฐ ๊ตฌ๋…์€ ์„œ๋กœ ๋‹ค๋ฅธ ํ•„ํ„ฐ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ „ ์„ธ๊ณ„ ์—ฌ๋Ÿฌ ์ง€์—ญ์—์„œ ๋‰ด์Šค๋ฅผ ์ˆ˜์‹ ํ•˜๋Š” ์ฃผ์ œ๊ฐ€ ์žˆ์œผ๋ฉด ํŠน์ • ๋ฆฌ์ „์—์„œ๋งŒ ๊ฒŒ์‹œ๋˜๋Š” ๋‰ด์Šค๋ฅผ ํ•„ํ„ฐ๋งํ•˜๋„๋ก ๊ตฌ๋…์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌ์„ฑ์˜ ๊ฒฝ์šฐ ์ฃผ์ œ ๋ฉ”์‹œ์ง€ ์†์„ฑ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋‰ด์Šค ๊ฒŒ์‹œ ๋ฆฌ์ „์„ ์ „๋‹ฌํ•˜๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ•„ํ„ฐ๊ฐ€ ํฌํ•จ๋œ ๊ตฌ๋…์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์œผ๋ฉด Pub/Sub๊ฐ€ ์ž๋™์œผ๋กœ ํ™•์ธํ•˜๋Š” ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•œ ์•„์›ƒ๋ฐ”์šด๋“œ ๋ฉ”์‹œ์ง€ ์š”๊ธˆ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฉ”์‹œ์ง€์—๋Š” ๋ฉ”์‹œ์ง€ ์ „์†ก ์š”๊ธˆ ๋ฐ ํƒ์ƒ‰ ๊ด€๋ จ ์Šคํ† ๋ฆฌ์ง€ ์š”๊ธˆ์ด ๋ถ€๊ณผ๋ฉ๋‹ˆ๋‹ค.

ํ•„ํ„ฐ๋กœ ๊ตฌ๋… ๋งŒ๋“ค๊ธฐ

Pull ๋ฐ Push ๊ตฌ๋…์€ ํ•„ํ„ฐ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ตฌ๋…์ž๋Š” StreamingPull API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ตฌ๋…์ž๋ฅผ ํฌํ•จํ•˜์—ฌ ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ๋…์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Google Cloud ์ฝ˜์†”, Google Cloud CLI, ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋˜๋Š” Pub/Sub API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„ํ„ฐ๋กœ ๊ตฌ๋…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฝ˜์†”

ํ•„ํ„ฐ๋กœ Pull ๊ตฌ๋…์„ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

  1. Google Cloud ์ฝ˜์†”์—์„œ ๊ตฌ๋… ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    ๊ตฌ๋… ํŽ˜์ด์ง€๋กœ ์ด๋™

  2. ๊ตฌ๋… ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  3. ๊ตฌ๋… ID๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  4. ๋“œ๋กญ๋‹ค์šด ๋ฉ”๋‰ด์—์„œ ํ•˜๋‚˜์˜ ์ฃผ์ œ๋ฅผ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ตฌ๋…์€ ์ฃผ์ œ์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.

  5. ๊ตฌ๋… ํ•„ํ„ฐ ์„น์…˜์—์„œ ํ•„ํ„ฐ ํ‘œํ˜„์‹์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  6. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

ํ•„ํ„ฐ๋กœ Push ๊ตฌ๋…์„ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

  1. Google Cloud ์ฝ˜์†”์—์„œ ๊ตฌ๋… ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    ๊ตฌ๋… ํŽ˜์ด์ง€๋กœ ์ด๋™

  2. ๊ตฌ๋… ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  3. ๊ตฌ๋… ID๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  4. ๋“œ๋กญ๋‹ค์šด ๋ฉ”๋‰ด์—์„œ ํ•˜๋‚˜์˜ ์ฃผ์ œ๋ฅผ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ตฌ๋…์€ ์ฃผ์ œ์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.

  5. ์ „์†ก ์œ ํ˜• ์„น์…˜์—์„œ Push๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  6. ์—”๋“œํฌ์ธํŠธ URL ํ•„๋“œ์—์„œ Push ์—”๋“œํฌ์ธํŠธ์˜ URL์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  7. ๊ตฌ๋… ํ•„ํ„ฐ ์„น์…˜์—์„œ ํ•„ํ„ฐ ํ‘œํ˜„์‹์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  8. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

gcloud

ํ•„ํ„ฐ๋กœ Pull ๊ตฌ๋…์„ ๋งŒ๋“ค๋ ค๋ฉด gcloud pubsub subscriptions create ๋ช…๋ น์–ด๋ฅผ --message-filter ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  • SUBSCRIPTION_ID: ์ƒ์„ฑํ•  ๊ตฌ๋…์˜ ID
  • TOPIC_ID: ๊ตฌ๋…์— ์—ฐ๊ฒฐํ•  ์ฃผ์ œ์˜ ID
  • FILTER: ํ•„ํ„ฐ๋ง ๊ตฌ๋ฌธ์˜ ํ‘œํ˜„์‹

ํ•„ํ„ฐ๋กœ Push ๊ตฌ๋…์„ ๋งŒ๋“ค๋ ค๋ฉด gcloud pubsub subscriptions create ๋ช…๋ น์–ด๋ฅผ --push-endpoint ๋ฐ --message-filter ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  • SUBSCRIPTION_ID: ์ƒ์„ฑํ•  ๊ตฌ๋…์˜ ID
  • TOPIC_ID: ๊ตฌ๋…์— ์—ฐ๊ฒฐํ•  ์ฃผ์ œ์˜ ID
  • PUSH_ENDPOINT: ํ‘ธ์‹œ ๊ตฌ๋…์ž๊ฐ€ ์‹คํ–‰๋˜๋Š” ์„œ๋ฒ„์˜ URL
  • FILTER: ํ•„ํ„ฐ๋ง ๊ตฌ๋ฌธ์˜ ํ‘œํ˜„์‹

REST

ํ•„ํ„ฐ๋กœ ๊ตฌ๋…์„ ๋งŒ๋“ค๋ ค๋ฉด projects.subscriptions.create ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  • PROJECT_ID: ๊ตฌ๋…์„ ๋งŒ๋“ค๋ ค๋Š” ํ”„๋กœ์ ํŠธ์˜ ํ”„๋กœ์ ํŠธ ID
  • SUBSCRIPTION_ID: ์ƒ์„ฑํ•  ๊ตฌ๋…์˜ ID

ํ•„ํ„ฐ๋กœ Pull ๊ตฌ๋…์„ ๋งŒ๋“ค๋ ค๋ฉด ์š”์ฒญ ๋ณธ๋ฌธ์— ํ•„ํ„ฐ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

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

๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  • PROJECT_ID: ์ฃผ์ œ๊ฐ€ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์˜ ํ”„๋กœ์ ํŠธ ID
  • TOPIC_ID: ๊ตฌ๋…์— ์—ฐ๊ฒฐํ•  ์ฃผ์ œ์˜ ID
  • FILTER: ํ•„ํ„ฐ๋ง ๊ตฌ๋ฌธ์˜ ํ‘œํ˜„์‹

ํ•„ํ„ฐ๋กœ Push ๊ตฌ๋…์„ ๋งŒ๋“ค๋ ค๋ฉด Push ์—”๋“œํฌ์ธํŠธ ๋ฐ ํ•„ํ„ฐ๋ฅผ ์š”์ฒญ ๋ณธ๋ฌธ์— ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

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

๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  • PROJECT_ID: ์ฃผ์ œ๊ฐ€ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์˜ ํ”„๋กœ์ ํŠธ ID
  • TOPIC_ID: ๊ตฌ๋…์— ์—ฐ๊ฒฐํ•  ์ฃผ์ œ์˜ ID
  • PUSH_ENDPOINT: ํ‘ธ์‹œ ๊ตฌ๋…์ž๊ฐ€ ์‹คํ–‰๋˜๋Š” ์„œ๋ฒ„์˜ URL
  • FILTER: ํ•„ํ„ฐ๋ง ๊ตฌ๋ฌธ์˜ ํ‘œํ˜„์‹

C++

์ด ์ƒ˜ํ”Œ์„ ์‹œ๋„ํ•˜๊ธฐ ์ „์— ๋น ๋ฅธ ์‹œ์ž‘: ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์˜ C++ ์„ค์ • ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ์ž์„ธํ•œ ๋‚ด์šฉ์€ 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#

์ด ์ƒ˜ํ”Œ์„ ์‹œ๋„ํ•˜๊ธฐ ์ „์— ๋น ๋ฅธ ์‹œ์ž‘: ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์˜ C# ์„ค์ • ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ์ž์„ธํ•œ ๋‚ด์šฉ์€ 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

๋‹ค์Œ ์ƒ˜ํ”Œ์—์„œ๋Š” Go Pub/Sub ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ฃผ์š” ๋ฒ„์ „ (v2)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„์ง v1 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด v2๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”. v1 ์ฝ”๋“œ ์ƒ˜ํ”Œ ๋ชฉ๋ก์„ ๋ณด๋ ค๋ฉด ์ง€์› ์ค‘๋‹จ๋œ ์ฝ”๋“œ ์ƒ˜ํ”Œ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

์ด ์ƒ˜ํ”Œ์„ ์‹œ๋„ํ•˜๊ธฐ ์ „์— ๋น ๋ฅธ ์‹œ์ž‘: ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์˜ Go ์„ค์ • ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Pub/Sub Go API ์ฐธ๊ณ  ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsub/v2"
	"cloud.google.com/go/pubsub/v2/apiv1/pubsubpb"
)

func createWithFilter(w io.Writer, projectID, topic, subscription, filter string) error {
	// Receive messages with attribute key "author" and value "unknown".
	// projectID := "my-project-id"
	// topic := "projects/my-project-id/topics/my-topic"
	// subscription := "projects/my-project/subscriptions/my-sub"
	// filter := "attributes.author=\"unknown\""
	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.SubscriptionAdminClient.CreateSubscription(ctx, &pubsubpb.Subscription{
		Name:   subscription,
		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 ์„ค์ • ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Pub/Sub ์ž๋ฐ” 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

์ด ์ƒ˜ํ”Œ์„ ์‹œ๋„ํ•˜๊ธฐ ์ „์— ๋น ๋ฅธ ์‹œ์ž‘: ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์˜ Node.js ์„ค์ • ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ์ž์„ธํ•œ ๋‚ด์šฉ์€ 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

์ด ์ƒ˜ํ”Œ์„ ์‹œ๋„ํ•˜๊ธฐ ์ „์— ๋น ๋ฅธ ์‹œ์ž‘: ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์˜ Node.js ์„ค์ • ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ์ž์„ธํ•œ ๋‚ด์šฉ์€ 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

์ด ์ƒ˜ํ”Œ์„ ์‹œ๋„ํ•˜๊ธฐ ์ „์— ๋น ๋ฅธ ์‹œ์ž‘: ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์˜ PHP ์„ค์ • ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Pub/Sub PHP API ์ฐธ์กฐ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

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

์ด ์ƒ˜ํ”Œ์„ ์‹œ๋„ํ•˜๊ธฐ ์ „์— ๋น ๋ฅธ ์‹œ์ž‘: ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์˜ Python ์„ค์ • ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ์ž์„ธํ•œ ๋‚ด์šฉ์€ 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

๋‹ค์Œ ์ƒ˜ํ”Œ์—์„œ๋Š” Ruby Pub/Sub ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ v3์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„์ง v2 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด v3๋กœ์˜ ์ด์ „ ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”. Ruby v2 ์ฝ”๋“œ ์ƒ˜ํ”Œ ๋ชฉ๋ก์„ ๋ณด๋ ค๋ฉด ์ง€์› ์ค‘๋‹จ๋œ ์ฝ”๋“œ ์ƒ˜ํ”Œ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

์ด ์ƒ˜ํ”Œ์„ ์‹œ๋„ํ•˜๊ธฐ ์ „์— ๋น ๋ฅธ ์‹œ์ž‘: ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์˜ Ruby ์„ค์ • ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Pub/Sub Ruby API ์ฐธ๊ณ  ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

# project_id = "your-project-id"
# topic_id = "your-topic-id"
# subscription_id = "your-subscription-id"
# filter = "attributes.author=\"unknown\""

pubsub = Google::Cloud::PubSub.new project_id: project_id
subscription_admin = pubsub.subscription_admin

subscription = subscription_admin.create_subscription \
  name: pubsub.subscription_path(subscription_id),
  topic: pubsub.topic_path(topic_id),
  filter: filter

puts "Created subscription with filtering enabled: #{subscription_id}"

ํ•„ํ„ฐ์˜ ์ตœ๋Œ€ ๊ธธ์ด๋Š” 256๋ฐ”์ดํŠธ์ž…๋‹ˆ๋‹ค. ํ•„ํ„ฐ๋Š” ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ๊ตฌ๋… ์†์„ฑ์ž…๋‹ˆ๋‹ค. ๊ตฌ๋…์„ ๋งŒ๋“  ํ›„์—๋Š” ํ•„ํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌ๋…์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

ํ•„ํ„ฐ๊ฐ€ ๋ฐฑ๋กœ๊ทธ ์ธก์ •ํ•ญ๋ชฉ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ

๋ฐฉ๊ธˆ ๋งŒ๋“  ๊ตฌ๋…์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋ ค๋ฉด ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ ๊ตฌ๋… ๋ชจ๋‹ˆํ„ฐ๋ง์„ ์ฐธ์กฐํ•˜์„ธ์š”.

ํ•„ํ„ฐ๋ง์„ ์‚ฌ์šฉ ์„ค์ •ํ•œ ๊ฒฝ์šฐ ๋ฐฑ๋กœ๊ทธ ์ธก์ •ํ•ญ๋ชฉ์—๋Š” ํ•„ํ„ฐ์™€ ์ผ์น˜ํ•˜๋Š” ๋ฉ”์‹œ์ง€์˜ ๋ฐ์ดํ„ฐ๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋ฐฑ๋กœ๊ทธ ์ธก์ •ํ•ญ๋ชฉ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

  • 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

์ด๋Ÿฌํ•œ ์ธก์ •ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด Pub/Sub ์ธก์ •ํ•ญ๋ชฉ ๋ชฉ๋ก์„ ์ฐธ์กฐํ•˜์„ธ์š”.

๊ตฌ๋… ํ•„ํ„ฐ ์—…๋ฐ์ดํŠธ

๊ธฐ์กด ๊ตฌ๋…์˜ ํ•„ํ„ฐ๋Š” ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ์ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ๋”ฐ๋ฅด์„ธ์š”.

  1. ํ•„ํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•  ๊ตฌ๋…์˜ ์Šค๋ƒ…์ƒท์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    ์ฝ˜์†”์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šค๋ƒ…์ƒท์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์Šค๋ƒ…์ƒท ๋งŒ๋“ค๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

  2. ์ƒˆ ํ•„ํ„ฐ๋กœ ์ƒˆ ๊ตฌ๋…์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    ํ•„ํ„ฐ๋กœ ๊ตฌ๋…์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ•„ํ„ฐ๋กœ ๊ตฌ๋… ๋งŒ๋“ค๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

  3. Google Cloud ์ฝ˜์†”์—์„œ Pub/Sub ๊ตฌ๋… ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    ๊ตฌ๋… ํŽ˜์ด์ง€๋กœ ์ด๋™

  4. ๋ฐฉ๊ธˆ ๋งŒ๋“  ๊ตฌ๋…์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  5. ๊ตฌ๋… ์„ธ๋ถ€์ •๋ณด ํŽ˜์ด์ง€์—์„œ ๋ฉ”์‹œ์ง€ ๋‹ค์‹œ๋ณด๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  6. ํƒ์ƒ‰์—์„œ ์Šค๋ƒ…์ƒท๊นŒ์ง€๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  7. 1๋‹จ๊ณ„์—์„œ ์›๋ž˜ ๊ตฌ๋…์— ๋Œ€ํ•ด ๋งŒ๋“  ์Šค๋ƒ…์ƒท์„ ์„ ํƒํ•œ ํ›„ ํƒ์ƒ‰์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    ์ „ํ™˜ ์ค‘์— ๋ฉ”์‹œ์ง€๊ฐ€ ์†์‹ค๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  8. ์ƒˆ ๊ตฌ๋…์„ ์‚ฌ์šฉํ•˜๋„๋ก ๊ตฌ๋…์ž๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

์ด ์ ˆ์ฐจ๋ฅผ ์™„๋ฃŒํ•œ ํ›„์—๋Š” ์›๋ž˜ ๊ตฌ๋…์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•„ํ„ฐ๋ฅผ ๋งŒ๋“œ๋Š” ๊ตฌ๋ฌธ

๋ฉ”์‹œ์ง€๋ฅผ ํ•„ํ„ฐ๋งํ•˜๋ ค๋ฉด ์†์„ฑ์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ํ‘œํ˜„์‹์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์†์„ฑ์˜ ํ‚ค ๋˜๋Š” ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋Š” ํ‘œํ˜„์‹์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. attributes ์‹๋ณ„์ž๋Š” ๋ฉ”์‹œ์ง€์˜ ์†์„ฑ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ํ…Œ์ด๋ธ”์˜ ํ•„ํ„ฐ๋Š” name ์†์„ฑ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

ํ•„ํ„ฐ ์„ค๋ช…
attributes:name name ์†์„ฑ์ด ์žˆ๋Š” ๋ฉ”์‹œ์ง€
NOT attributes:name name ์†์„ฑ์ด ์—†๋Š” ๋ฉ”์‹œ์ง€
attributes.name = "com" name ์†์„ฑ ๋ฐ com ๊ฐ’์ด ์žˆ๋Š” ๋ฉ”์‹œ์ง€
attributes.name != "com" name ์†์„ฑ ๋ฐ com ๊ฐ’์ด ์—†๋Š” ๋ฉ”์‹œ์ง€
hasPrefix(attributes.name, "co") name ์†์„ฑ ๋ฐ co๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฐ’์ด ์žˆ๋Š” ๋ฉ”์‹œ์ง€
NOT hasPrefix(attributes.name, "co") name ์†์„ฑ์ด ์—†๊ณ  co๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฐ’์ด ์žˆ๋Š” ๋ฉ”์‹œ์ง€

ํ•„ํ„ฐ ํ‘œํ˜„์‹์˜ ๋น„๊ต ์—ฐ์‚ฐ์ž

๋‹ค์Œ ๋น„๊ต ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์†์„ฑ์„ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • :
  • =
  • !=

: ์—ฐ์‚ฐ์ž๋Š” ์†์„ฑ ๋ชฉ๋ก์—์„œ ์ผ์น˜ํ•˜๋Š” ํ‚ค๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

attributes:KEY

๋“ฑํ˜ธ ์—ฐ์‚ฐ์ž๋Š” ์ผ์น˜ํ•˜๋Š” ํ‚ค์™€ ๊ฐ’์„ ์ฐพ์Šต๋‹ˆ๋‹ค. ๊ฐ’์€ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

attributes.KEY = "VALUE"

๋“ฑํ˜ธ ์—ฐ์‚ฐ์ž๊ฐ€ ์žˆ๋Š” ํ‘œํ˜„์‹์€ ํ‚ค๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•˜๋ฉฐ ๋“ฑํ˜ธ ์—ฐ์‚ฐ์ž๋Š” ํ‚ค์™€ ๊ฐ’์„ ๋น„๊ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ์œ ํšจ: ํ•„ํ„ฐ๊ฐ€ ํ‚ค์™€ ๊ฐ’์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

    attributes.name = "com"
    
  • ์œ ํšจํ•˜์ง€ ์•Š์Œ: ํ•„ํ„ฐ์˜ ์™ผ์ชฝ ์ธก๋ฉด์ด ๊ฐ’์ž…๋‹ˆ๋‹ค.

    "com" = attributes.name
    
  • ์œ ํšจํ•˜์ง€ ์•Š์Œ: ํ•„ํ„ฐ๊ฐ€ ๋‘ ํ‚ค๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

    attributes.name = attributes.website
    

ํ‚ค์™€ ๊ฐ’์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜๋ฉฐ ์†์„ฑ๊ณผ ์ •ํ™•ํ•˜๊ฒŒ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ‚ค์— ํ•˜์ดํ”ˆ, ๋ฐ‘์ค„, ์˜์ˆซ์ž ๋ฌธ์ž ์ด์™ธ์˜ ๋ฌธ์ž๊ฐ€ ํฌํ•จ๋œ ๊ฒฝ์šฐ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

ํ•„ํ„ฐ์— ๋ฐฑ์Šฌ๋ž˜์‹œ, ๋”ฐ์˜ดํ‘œ, ์ธ์‡„๋˜์ง€ ์•Š๋Š” ๋ฌธ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด ๋‚ด์—์„œ ๋ฌธ์ž๋ฅผ ์ด์Šค์ผ€์ดํ”„ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด ๋‚ด์—์„œ ์œ ๋‹ˆ์ฝ”๋“œ, 16์ง„์ˆ˜, 8์ง„์ˆ˜ ์ด์Šค์ผ€์ดํ”„ ์‹œํ€€์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์œ ํšจ: ํ•„ํ„ฐ๊ฐ€ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด ๋‚ด์˜ ๋ฌธ์ž๋ฅผ ์ด์Šค์ผ€์ดํ”„ํ•ฉ๋‹ˆ๋‹ค.

    attributes:"\u307F\u3093\u306A"
    
  • ์œ ํšจํ•˜์ง€ ์•Š์Œ: ํ•„ํ„ฐ๊ฐ€ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด ์—†์ด ๋ฌธ์ž๋ฅผ ์ด์Šค์ผ€์ดํ”„ํ•ฉ๋‹ˆ๋‹ค.

    attributes:\u307F\u3093\u306A
    

ํ•„ํ„ฐ ํ‘œํ˜„์‹์˜ ๋ถˆ๋ฆฌ์–ธ ์—ฐ์‚ฐ์ž

ํ•„ํ„ฐ์— ๋ถ€์šธ ์—ฐ์‚ฐ์ž AND, NOT, OR๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฐ์‚ฐ์ž๋Š” ๋Œ€๋ฌธ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ํ•„ํ„ฐ๋Š” iana.org/language_tag ์†์„ฑ์ด ์žˆ๊ณ  name ์†์„ฑ๊ณผ com ๊ฐ’์ด ์—†๋Š” ๋ฉ”์‹œ์ง€์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

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

NOT ์—ฐ์‚ฐ์ž์˜ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๊ฐ€์žฅ ๋†’์Šต๋‹ˆ๋‹ค. AND ๋ฐ OR ์—ฐ์‚ฐ์ž๋ฅผ ๊ฒฐํ•ฉํ•˜๋ ค๋ฉด ๊ด„ํ˜ธ์™€ ์™„์ „ํ•œ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ์œ ํšจ: AND ๋ฐ OR ์—ฐ์‚ฐ์ž(๊ด„ํ˜ธ ํฌํ•จ)

    attributes:"iana.org/language_tag" AND (attributes.name = "net" OR attributes.name = "org")
    
  • ์œ ํšจํ•˜์ง€ ์•Š์Œ: ๊ด„ํ˜ธ ์—†๋Š” AND ๋ฐ OR ์—ฐ์‚ฐ์ž

    attributes:"iana.org/language_tag" AND attributes.name = "net" OR attributes.name = "org"
    
  • ์œ ํšจํ•˜์ง€ ์•Š์Œ: AND ์—ฐ์‚ฐ์ž์™€ OR ์—ฐ์‚ฐ์ž๊ฐ€ ๋ถˆ์™„์ „ํ•œ ํ‘œํ˜„์‹์„ ๊ฒฐํ•ฉํ•จ

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

NOT ์—ฐ์‚ฐ์ž ๋Œ€์‹  ๋‹จํ•ญ ๋บ„์…ˆ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

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

ํ•„ํ„ฐ ํ‘œํ˜„์‹์˜ ํ•จ์ˆ˜

hasPrefix ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•˜์œ„ ๋ฌธ์ž์—ด๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฐ’์ด ์žˆ๋Š” ์†์„ฑ์„ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. hasPrefix๋Š” ํ•„ํ„ฐ์—์„œ ์ง€์›๋˜๋Š” ์œ ์ผํ•œ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

hasPrefix ํ•จ์ˆ˜์—์„œ๋Š” ํ”„๋ฆฌํ”ฝ์Šค ์ผ์น˜๊ฐ€ ์ง€์›๋˜์ง€๋งŒ ์ผ๋ฐ˜ ์ •๊ทœ ํ‘œํ˜„์‹์ด ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

hasPrefix(attributes.KEY, "SUBSTRING")

๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  • KEY: ์†์„ฑ์˜ ์ด๋ฆ„
  • SUBSTRING: ๊ฐ’์˜ ํ•˜์œ„ ๋ฌธ์ž์—ด