Как использовать поиск по тексту

Используйте функции текстового поиска в Cloud Firestore, чтобы искать определенные строки в документах.

Требования к версиям

Для текстового поиска требуется база данных Firestore Enterprise.

Подготовка

Чтобы выполнить текстовый поиск, сначала необходимо создать текстовые индексы для полей, по которым нужно выполнить поиск.

Чтобы выполнить текстовый поиск, используйте выражение documentMatches в параметре query этапа search(...).

Поиск выполняется только по полям, проиндексированным с помощью текстового индекса. Если доступно несколько индексов, Cloud Firestore выбирает один из них для выполнения операции.

Web

const result = await execute(db.pipeline().collection('restaurants')
  .search({
    query: documentMatches('waffles')
  }));
iOS
let snapshot = try await db.pipeline().collection("restaurants")
  .search(query: DocumentMatches("waffles"))
  .execute()

Kotlin

val pipeline = db.pipeline().collection("restaurants")
    .search(SearchStage.withQuery(documentMatches("waffles")))

Java

Pipeline pipeline = db.pipeline().collection("restaurants")
        .search(SearchStage.withQuery(documentMatches("waffles")));
Node.js
await db.pipeline().collection('restaurants')
  .search({
    query: documentMatches('waffles')
  })
  .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import DocumentMatches

results = (
    client.pipeline()
    .collection("restaurants")
    .search(DocumentMatches("waffles"))
    .execute()
)
Java
Pipeline.Snapshot results1 =
    firestore.pipeline().collection("restaurants")
        .search(Search.withQuery(documentMatches("waffles")))
        .execute().get();
Проложить маршрут
snapshot := client.Pipeline().
	Collection("restaurants").
	Search(firestore.WithSearchQuery(firestore.DocumentMatches("waffles"))).
	Execute(ctx)

Поиск точного совпадения

Чтобы найти точное совпадение, заключите запрос в кавычки ("):

Web

const result = await execute(db.pipeline().collection('restaurants')
  .search({
    query: documentMatches('"belgian waffles"')
  }));
iOS
let snapshot = try await db.pipeline().collection("restaurants")
  .search(query: DocumentMatches("\"belgian waffles\""))
  .execute()

Kotlin

val pipeline = db.pipeline().collection("restaurants")
    .search(SearchStage.withQuery(documentMatches("\"belgian waffles\"")))

Java

Pipeline pipeline = db.pipeline().collection("restaurants")
        .search(SearchStage.withQuery(documentMatches("\"belgian waffles\"")));
Node.js
await db.pipeline().collection('restaurants')
  .search({
    query: documentMatches('"belgian waffles"')
  })
  .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import DocumentMatches

results = (
    client.pipeline()
    .collection("restaurants")
    .search(DocumentMatches('"belgian waffles"'))
    .execute()
)
Java
Pipeline.Snapshot results2 =
    firestore.pipeline().collection("restaurants")
        .search(Search.withQuery(documentMatches("\"belgian waffles\"")))
        .execute().get();
Проложить маршрут
snapshot := client.Pipeline().
	Collection("restaurants").
	Search(firestore.WithSearchQuery(firestore.DocumentMatches("\"belgian waffles\""))).
	Execute(ctx)

Как выполнить поиск по комбинации слов

Чтобы найти сочетание слов (логический оператор AND), введите их через пробел:

Web

const result = await execute(db.pipeline().collection('restaurants')
  .search({
    query: documentMatches('waffles eggs')
  }));
iOS
let snapshot = try await db.pipeline().collection("restaurants")
  .search(query: DocumentMatches("waffles eggs"))
  .execute()

Kotlin

val pipeline = db.pipeline().collection("restaurants")
    .search(SearchStage.withQuery(documentMatches("waffles eggs")))

Java

Pipeline pipeline = db.pipeline().collection("restaurants")
        .search(SearchStage.withQuery(documentMatches("waffles eggs")));
Node.js
await db.pipeline().collection('restaurants')
  .search({
    query: documentMatches('waffles eggs')
  })
  .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import DocumentMatches

results = (
    client.pipeline()
    .collection("restaurants")
    .search(DocumentMatches("waffles eggs"))
    .execute()
)
Java
firestore.collection("restaurants").add(new HashMap<String, Object>() {{
  put("name", "Morning Diner");
  put("description", "Start your day with waffles and eggs.");
}});
Pipeline.Snapshot results3 =
    firestore.pipeline().collection("restaurants")
        .search(Search.withQuery(documentMatches("waffles eggs")))
        .execute().get();
Проложить маршрут
snapshot := client.Pipeline().
	Collection("restaurants").
	Search(firestore.WithSearchQuery(firestore.DocumentMatches("waffles eggs"))).
	Execute(ctx)

Исключить слово

Чтобы исключить слово, поставьте перед ним дефис (-):

Web

const result = await execute(db.pipeline().collection('restaurants')
  .search({
    query: documentMatches('coffee -waffles')
  }));
iOS
let snapshot = try await db.pipeline().collection("restaurants")
  .search(query: DocumentMatches("coffee -waffles"))
  .execute()

Kotlin

val pipeline = db.pipeline().collection("restaurants")
    .search(SearchStage.withQuery(documentMatches("waffles eggs")))

Java

Pipeline pipeline = db.pipeline().collection("restaurants")
        .search(SearchStage.withQuery(documentMatches("coffee -waffles")));
Node.js
await db.pipeline().collection('restaurants')
  .search({
    query: documentMatches('-waffles')
  })
  .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import DocumentMatches

results = (
    client.pipeline()
    .collection("restaurants")
    .search(DocumentMatches("-waffles"))
    .execute()
)
Java
firestore.collection("restaurants").add(new HashMap<String, Object>() {{
  put("name", "City Coffee");
  put("description", "Premium coffee and pastries.");
}});
Pipeline.Snapshot results4 =
    firestore.pipeline().collection("restaurants")
        .search(Search.withQuery(documentMatches("-waffles")))
        .execute().get();
Проложить маршрут
snapshot := client.Pipeline().
	Collection("restaurants").
	Search(firestore.WithSearchQuery(firestore.DocumentMatches("-waffles"))).
	Execute(ctx)

Вы также можете исключить фразу, например pizza -"New York".

Сортировка результатов

По умолчанию Cloud Firestore сортирует результаты по времени создания документа от новых к старым. Вы можете отсортировать результаты по оценке соответствия, но для этого потребуется больше вычислений, чтобы рассчитать и сравнить точную оценку каждого документа:

Чтобы отсортировать результаты по оценке соответствия:

Web

const result = await execute(db.pipeline().collection('restaurants')
  .search({
    query: documentMatches('waffles'),
    sort: score().descending()
  }));
iOS
let snapshot = try await db.pipeline().collection("restaurants")
  .search(
      query: DocumentMatches("waffles"),
      sort: [Score().descending()]
      )
  .execute()

Kotlin

val pipeline = db.pipeline().collection("restaurants")
    .search(SearchStage
              .withQuery(documentMatches("waffles"))
              .withSort(score().descending())
              )
Node.js
await db.pipeline().collection('restaurants')
  .search({
    query: documentMatches('waffles'),
    sort: score().descending()
  })
  .execute();

Добавление полей в документы, возвращаемые на этапе поиска

Вы можете использовать addFields, чтобы добавить поля в документы, возвращенные на этапе поиска. Выражения, возвращающие значения, вычисленные на этапе поиска, например score(), можно использовать в addFields на этапе поиска, чтобы записать эти значения в выходные документы.

В следующем примере поле score добавляется в документы, возвращенные на этапе поиска:

Web

const result = await execute(db.pipeline().collection('restaurants')
  .search({
    query: 'menu:waffles',
    addFields: [
        score().as('score'),
    ]
  }));
iOS
let snapshot = try await db.pipeline().collection("restaurants")
  .search(
    query: DocumentMatches("waffles"),
    addFields: [
      Score().as("score")
    ]
  )
  .execute()

Kotlin

val pipeline = db.pipeline().collection("restaurants")
    .search(SearchStage.withQuery(documentMatches("waffles eggs")))

Java

Pipeline pipeline = db.pipeline().collection("restaurants")
        .search(
                SearchStage.withQuery(documentMatches("menu:waffles"))
                        .withAddFields(score().alias("score")));
Node.js
await db.pipeline().collection('restaurants')
  .search({
    query: field('menu').matches('waffles'),
    addFields: [
        score().as('score'),
    ]
  }).execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import DocumentMatches, Score
from google.cloud.firestore_v1.pipeline_stages import SearchOptions

results = (
    client.pipeline()
    .collection("restaurants")
    .search(
        SearchOptions(
            query=DocumentMatches("menu:waffles"),
            add_fields=[Score().as_("score")],
        )
    )
    .execute()
)
Java
Pipeline.Snapshot results5 =
    firestore.pipeline().collection("restaurants")
        .search(Search.withQuery(field("menu").regexMatch("waffles"))
            .withAddFields(score().as("score")))
        .execute().get();
Проложить маршрут
snapshot := client.Pipeline().
	Collection("restaurants").
	Search(
		firestore.WithSearchQuery(firestore.FieldOf("menu").RegexMatch("waffles")),
		firestore.WithSearchAddFields(firestore.Score().As("score")),
	).
	Execute(ctx)