Paginar os resultados
Nesta página
- Uso
- Considerações
- Recuperar ponto de referência
- Sintaxe
- Saída
- Atlas Search após um ponto de referência específico
searchAfter
Sintaxe- Saída
- Atlas Search antes de um ponto de referência específico
searchBefore
SintaxesearchBefore
Saída- Exemplos
searchSequenceToken
Query- Queries
searchAfter
esearchBefore
subsequentes
Em clusters Atlas executando MongoDB 6.0.13+ ou 7.0.5+, use o Atlas Search para recuperar os resultados da sua query $search
sequencialmente depois ou antes de um ponto de referência. Use as opções $search
searchAfter
ou searchBefore
para percorrer os resultados em ordem e criar funções "Próxima página" e "Página anterior" em seu aplicativo.
Uso
Para recuperar resultados paginados, execute as seguintes etapas:
Crie um índice nos campos que você deseja consultar.
Execute uma query
$search
que retorna um ponto de referência. Para saber mais, consulte Recuperar ponto de referência.Use o ponto de referência em sua query
$search
subsequente para recuperar o conjunto de documentos seguinte ou anterior nos resultados.Para saber mais sobre como recuperar resultados para criar uma função "Próxima página", consulte Atlas Search após um ponto de referência específico.
Para saber mais sobre como recuperar resultados para criar uma função de "Página anterior", consulte Atlas Search antes de um ponto de referência específico.
Para ir para uma página em seus resultados, combine
$skip
e$limit
com as opções$search
searchAfter
ousearchBefore
. Por exemplo, para ir para os resultados da página 3 para a página 5, com 10 resultados por página, faça o seguinte:Recupere resultados usando
searchAfter
com o ponto de referência do último resultado na página 3 (Result 30).Use
$skip
para pular os resultados 10 na página 4 (Resultados 31-40) e$limit
para limitar os resultados a 10 documentos.Retorne resultados para a página 5 (Resultados 41-50).
Aqui, usar
$skip
com a opçãosearchAfter
otimiza a consulta para pular apenas 1 página de resultados (10 documentos). Em comparação, se você usar$skip
sem a opção$search
searchAfter
, a consulta pulará 4 páginas de resultados (40 documentos). Para saber mais, consulte Ir da página 2 para a página 5 usandosearchAfter
e$skip
.
Considerações
Um empate ocorre quando você classifica em um campo para o qual vários documentos têm valores idênticos. O MongoDB não garante a ordenação de resultados de query vinculados, o que pode levar à duplicação e inconsistência quando você usa searchAfter
e searchBefore
. Aplique os seguintes princípios para garantir um comportamento de pesquisa determinístico:
Classifique sua query por um campo exclusivo para evitar empates de pontuação de relevância.
Se você quiser classificar principalmente por um campo não exclusivo, adicione uma cláusula de classificação secundária em um campo exclusivo para servir como desempate.
Classifique os resultados da consulta por um campo imutável. O Atlas Search reflete as atualizações que você faz em sua collection entre as queries inicial e subsequentes. Se você classificar por um campo mutável como
updated_time
e atualizar sua coleção entre a primeira e a segunda queries, o Atlas Search poderá ordenar os mesmos documentos de forma diferente.
Para aprender como classificar os resultados da query por um campo imutável ou único, consulte Classificar resultados do Atlas Search.
Recuperar ponto de referência
Para recuperar resultados de query em um determinado ponto, você deve fornecer o ponto de referência em sua query $search
. Você pode recuperar o ponto de referência usando a palavra-chave $meta
searchSequenceToken
no estágio $project
após o estágio $search
.
Sintaxe
1 [{ 2 "$search": { 3 "index": "<index-name>", 4 "<operator-name>"|"<collector-name>": { 5 <operator-specification>|<collector-specification> 6 } 7 "sort": { 8 "score": { 9 "$meta": "searchScore", _id:1 10 } 11 } 12 ... 13 }, 14 { 15 "$project": { 16 { "paginationToken" : { "$meta" : "searchSequenceToken" } } 17 }, 18 ... 19 }]
Saída
O searchSequenceToken
gera um token codificado de Base64para cada documento nos resultados. O comprimento do token aumenta com o número de campos especificados na opção de classificação da sua query. O token não está vinculado a um snapshot do banco de dados.
Os documentos nos resultados são classificados na ordem padrão, a menos que você especifique a opção sort
em sua query. Para saber mais sobre como classificar seus resultados, consulte Classificar resultados do Atlas Search.
Atlas Search após um ponto de referência específico
Para pesquisar um ponto de referência, você deve especificar o ponto de referência em sua query $search
usando a opção searchAfter
com o token gerado por searchSequenceToken
. Você pode usar o token gerado por searchSequenceToken
somente ao executar novamente a query $search
para a qual searchSequenceToken
gerou o token. A semântica (campos e valores de pesquisa) da query $search
subsequente na qual você usa o token deve ser idêntica à query para a qual searchSequenceToken
gerou o token.
Você pode utilizar a opção searchAfter
para construir uma função "Próxima Página" em seu aplicativo. Para uma demonstração disso, consulte o exemplo nesta página.
searchAfter
Sintaxe
1 { 2 "$search": { 3 "index": "<index-name>", 4 "<operator-name>"|"<collector-name>": { 5 <operator-specification>|<collector-specification> 6 }, 7 "searchAfter": "<base64-encoded-token>", 8 "sort": { 9 "score": { 10 "$meta": "searchScore", _id:1 11 } 12 } 13 ... 14 }, 15 "$project": { 16 { "paginationToken" : { "$meta" : "searchSequenceToken" } } 17 }, 18 ... 19 }
Saída
O Atlas Search retorna os documentos nos resultados após o token especificado. O Atlas Search retorna os tokens gerados para os documentos nos resultados porque você especificou o searchSequenceToken
no estágio $project
após o estágio $search
(como mostrado na linha 11). Esses tokens podem ser usados como ponto de referência para outra query com a mesma semântica.
Os documentos nos resultados são classificados na ordem padrão, a menos que você especifique a opção sort
em sua query. Para saber mais sobre como classificar seus resultados, consulte Classificar resultados do Atlas Search.
Atlas Search antes de um ponto de referência específico
Para o Atlas Search antes de um ponto de referência, você deve especificar o ponto de referência em sua query do $search
utilizando a opção searchBefore
com o token gerado pelo searchSequenceToken
. Você pode usar o token gerado por searchSequenceToken
somente quando executar novamente a query $search
para a qual searchSequenceToken
gerou o token. A semântica (campos e valores do Atlas Search ) da query subsequente do $search
subsequente na qual você usa o token deve ser idêntica à query para a qual o searchSequenceToken
gerou o token.
Você pode criar uma função "Página anterior" em seu aplicativo usando a opção searchBefore
. Para criar uma função "Página anterior", combine o seguinte:
Para uma demonstração disso, veja exemplos de query searchBefore
nesta página.
searchBefore
Sintaxe
1 { 2 "$search": { 3 "index": "<index-name>", 4 "<operator-name>"|"<collector-name>": { 5 <operator-specification>|<collector-specification> 6 }, 7 "searchBefore": "<base64-encoded-token>", 8 "sort": { 9 "score": { 10 "$meta": "searchScore", _id:1 11 } 12 } 13 ... 14 }, 15 "$project": { 16 { "paginationToken" : { "$meta" : "searchSequenceToken" } } 17 }, 18 ... 19 }
searchBefore
Saída
O Atlas Search retorna documentos nos resultados anteriores ao token especificado na ordem inversa. O Atlas Search também retorna os tokens gerados para os documentos nos resultados porque você especificou o searchSequenceToken
no estágio $project
após o estágio $search
(conforme mostrado na linha 11). Esses tokens podem ser usados como um ponto de referência para outra query com a mesma semântica.
Exemplos
Os exemplos a seguir usam a coleção sample-mflix.movies, que tem um índice do Atlas Search chamado default
com mapeamentos dinâmicos. Se você carregar a coleção e criar o índice, poderá executar as seguintes queries na coleção.
searchSequenceToken
Query
A consulta a seguir usa os estágios de pipeline a seguir:
$search
para fazer o seguinte:Atlas Search o termo
war
no campotitle
da coleção.Classifique os resultados primeiro por pontuação e depois pelo valor do campo
released
em ordem crescente para documentos com pontuações idênticas.
$limit
estágio para limitar os resultados a10
documentos.$project
estágio para fazer o seguinte:Inclua apenas os campos
title
ereleased
.Adicione os seguintes campos:
Campo chamado
paginationToken
que contém o token codificado em Base64 para cada documento.Campo chamado
score
que contém a pontuação de relevância de cada documento.
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "text": { 5 "path": "title", 6 "query": "war" 7 }, 8 "sort": {score: {$meta: "searchScore"}, "released": 1} 9 } 10 }, 11 { 12 "$limit": 10 13 }, 14 { 15 "$project": { 16 "_id": 0, 17 "title": 1, 18 "released": 1, 19 "paginationToken" : { "$meta" : "searchSequenceToken" }, 20 "score": {$meta: "searchScore"} 21 } 22 } 23 ])
1 [ 2 { 3 title: 'War', 4 released: ISODate('2002-03-14T00:00:00.000Z'), 5 paginationToken: 'CMFRGgYQup3BhQgaCSkAQCKS7AAAAA==', 6 score: 3.3774025440216064 7 }, 8 { 9 title: 'War', 10 released: ISODate('2014-09-21T00:00:00.000Z'), 11 paginationToken: 'CMelARoGELqdwYUIGgkpAAiClUgBAAA=', 12 score: 3.3774025440216064 13 }, 14 { 15 title: 'War Photographer', 16 paginationToken: 'CMBRGgYQuq+ngwgaAmAA', 17 score: 2.8268959522247314 18 }, 19 { 20 title: "Troma's War", 21 released: ISODate('1989-11-18T00:00:00.000Z'), 22 paginationToken: 'CL8kGgYQuq+ngwgaCSkAbP8QkgAAAA==', 23 score: 2.8268959522247314 24 }, 25 { 26 title: 'The War', 27 released: ISODate('1994-11-04T00:00:00.000Z'), 28 paginationToken: 'CI0wGgYQuq+ngwgaCSkAnIKEtgAAAA==', 29 score: 2.8268959522247314 30 }, 31 { 32 title: 'War Stories', 33 released: ISODate('1996-05-09T00:00:00.000Z'), 34 paginationToken: 'CPIyGgYQuq+ngwgaCSkA/DifwQAAAA==', 35 score: 2.8268959522247314 36 }, 37 { 38 title: "Gaston's War", 39 released: ISODate('1997-10-23T00:00:00.000Z'), 40 paginationToken: 'CMQ7GgYQuq+ngwgaCSkALPBSzAAAAA==', 41 score: 2.8268959522247314 42 }, 43 { 44 title: 'Shooting War', 45 released: ISODate('2000-12-07T00:00:00.000Z'), 46 paginationToken: 'CMJJGgYQuq+ngwgaCSkAOOhG4wAAAA==', 47 score: 2.8268959522247314 48 }, 49 { 50 title: "Varian's War", 51 released: ISODate('2001-04-22T00:00:00.000Z'), 52 paginationToken: 'CM5IGgYQuq+ngwgaCSkAGEkD5gAAAA==', 53 score: 2.8268959522247314 54 }, 55 { 56 title: "Hart's War", 57 released: ISODate('2002-02-15T00:00:00.000Z'), 58 paginationToken: 'CMtJGgYQuq+ngwgaCSkAjBYH7AAAAA==', 59 score: 2.8268959522247314 60 } 61 ]
Observação
Os tokens para os documentos em seus resultados podem ser diferentes. Substitua os tokens nas queries subsequentes pelos tokens que o Atlas Search retornou em seus resultados antes de executar as queries searchAfter
ou searchBefore
.
Queries searchAfter
e searchBefore
subsequentes
As queries a seguir usam o token de outra query com a mesma semântica para recuperar resultados paginados depois ou antes do token especificado. Se você executou o exemplo de QuerysearchSequenceToken
, os tokens para os documentos em seus resultados poderão ser diferentes. Certifique-se de substituir os tokens nas queries nesta seção pelos tokens retornados no resultado da query.
As queries usam os seguintes estágios de pipeline:
$search
estágio para fazer o seguinte:Pesquise documentos nos resultados da Atlas Search para o termo
war
no campotitle
.Classifique os resultados primeiro por pontuação e depois pelo valor do campo
released
em ordem crescente para documentos com pontuações idênticas.
$limit
estágio para limitar os resultados a10
documentos.$project
estágio para fazer o seguinte:Inclua apenas os campos
title
ereleased
nos documentos.Adicione os seguintes campos:
Campo chamado
paginationToken
que contém o token codificado em Base64 para cada documento.Campo chamado
score
que contém a pontuação de relevância de cada documento.
Atlas Search após o ponto de referência
A seguinte query solicita documentos nos resultados da Atlas Search que contêm o termo war
no campo title
após o ponto de referência especificado. Ele usa o token (na linha 58) associado ao último documento dos searchSequenceToken
Resultados da consulta como ponto de referência para recuperar os próximos 10
documentos nos resultados.
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "text": { 5 "path": "title", 6 "query": "war" 7 }, 8 "sort": {score: {$meta: "searchScore"}, "released": 1}, 9 "searchAfter": "CMtJGgYQuq+ngwgaCSkAjBYH7AAAAA==" 10 } 11 }, 12 { 13 "$limit": 10 14 }, 15 { 16 "$project": { 17 "_id": 0, 18 "title": 1, 19 "released": 1, 20 "paginationToken" : { "$meta" : "searchSequenceToken" }, 21 "score": { "$meta": "searchScore" } 22 } 23 } 24 ])
1 [ 2 { 3 title: 'The War', 4 released: ISODate('2007-09-23T00:00:00.000Z'), 5 paginationToken: 'CP9xGgYQuq+ngwgaCSkA1KkvFQEAAA==', 6 score: 2.8268959522247314 7 }, 8 { 9 title: 'War, Inc.', 10 released: ISODate('2008-06-13T00:00:00.000Z'), 11 paginationToken: 'COhuGgYQuq+ngwgaCSkAtDh/GgEAAA==', 12 score: 2.8268959522247314 13 }, 14 { 15 title: 'War, Inc.', 16 released: ISODate('2008-06-13T00:00:00.000Z'), 17 paginationToken: 'COluGgYQuq+ngwgaCSkAtDh/GgEAAA==', 18 score: 2.8268959522247314 19 }, 20 { 21 title: 'War Dance', 22 released: ISODate('2008-11-01T00:00:00.000Z'), 23 paginationToken: 'CONvGgYQuq+ngwgaCSkAYFlVHQEAAA==', 24 score: 2.8268959522247314 25 }, 26 { 27 title: 'War Horse', 28 released: ISODate('2011-12-25T00:00:00.000Z'), 29 paginationToken: 'CJWFARoGELqvp4MIGgkpAEyEcjQBAAA=', 30 score: 2.8268959522247314 31 }, 32 { 33 title: 'Cold War', 34 released: ISODate('2012-11-08T00:00:00.000Z'), 35 paginationToken: 'CJGUARoGELqvp4MIGgkpAPBQ3ToBAAA=', 36 score: 2.8268959522247314 37 }, 38 { 39 title: 'Drug War', 40 released: ISODate('2013-04-04T00:00:00.000Z'), 41 paginationToken: 'CMWTARoGELqvp4MIGgkpAMRX0j0BAAA=', 42 score: 2.8268959522247314 43 }, 44 { 45 title: 'War Story', 46 released: ISODate('2014-07-30T00:00:00.000Z'), 47 paginationToken: 'CJCdARoGELqvp4MIGgkpAPyQhEcBAAA=', 48 score: 2.8268959522247314 49 }, 50 { 51 title: 'A War', 52 released: ISODate('2015-09-10T00:00:00.000Z'), 53 paginationToken: 'CL2kARoGELqvp4MIGgkpAECNtE8BAAA=', 54 score: 2.8268959522247314 55 }, 56 { 57 title: 'War Pigs', 58 released: ISODate('2015-09-18T00:00:00.000Z'), 59 paginationToken: 'CJ6kARoGELqvp4MIGgkpACDA3U8BAAA=', 60 score: 2.8268959522247314 61 } 62 ]
Atlas Search antes do ponto de referência
A consulta a seguir solicita os resultados do Atlas Search para o termo war
no campo title
antes do ponto de referência especificado. Ele usa o token (na linha 59) associado ao último documento nos resultados da consulta de amostra searchAfter
como o ponto de referência para recuperar os documentos 10
anteriores dos resultados.
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "text": { 5 "path": "title", 6 "query": "war" 7 }, 8 "sort": {score: {$meta: "searchScore"}, "released": 1}, 9 "searchBefore": "CJ6kARoGELqvp4MIGgkpACDA3U8BAAA=" 10 } 11 }, 12 { 13 "$limit": 10 14 }, 15 { 16 "$project": { 17 "_id": 0, 18 "title": 1, 19 "released": 1, 20 "paginationToken" : { "$meta" : "searchSequenceToken" }, 21 "score": { "$meta": "searchScore" } 22 } 23 } 24 ])
1 [ 2 { 3 title: 'A War', 4 released: ISODate('2015-09-10T00:00:00.000Z'), 5 paginationToken: 'CL2kARoGELqvp4MIGgkpAECNtE8BAAA=', 6 score: 2.8268959522247314 7 }, 8 { 9 title: 'War Story', 10 released: ISODate('2014-07-30T00:00:00.000Z'), 11 paginationToken: 'CJCdARoGELqvp4MIGgkpAPyQhEcBAAA=', 12 score: 2.8268959522247314 13 }, 14 { 15 title: 'Drug War', 16 released: ISODate('2013-04-04T00:00:00.000Z'), 17 paginationToken: 'CMWTARoGELqvp4MIGgkpAMRX0j0BAAA=', 18 score: 2.8268959522247314 19 }, 20 { 21 title: 'Cold War', 22 released: ISODate('2012-11-08T00:00:00.000Z'), 23 paginationToken: 'CJGUARoGELqvp4MIGgkpAPBQ3ToBAAA=', 24 score: 2.8268959522247314 25 }, 26 { 27 title: 'War Horse', 28 released: ISODate('2011-12-25T00:00:00.000Z'), 29 paginationToken: 'CJWFARoGELqvp4MIGgkpAEyEcjQBAAA=', 30 score: 2.8268959522247314 31 }, 32 { 33 title: 'War Dance', 34 released: ISODate('2008-11-01T00:00:00.000Z'), 35 paginationToken: 'CONvGgYQuq+ngwgaCSkAYFlVHQEAAA==', 36 score: 2.8268959522247314 37 }, 38 { 39 title: 'War, Inc.', 40 released: ISODate('2008-06-13T00:00:00.000Z'), 41 paginationToken: 'COluGgYQuq+ngwgaCSkAtDh/GgEAAA==', 42 score: 2.8268959522247314 43 }, 44 { 45 title: 'War, Inc.', 46 released: ISODate('2008-06-13T00:00:00.000Z'), 47 paginationToken: 'COhuGgYQuq+ngwgaCSkAtDh/GgEAAA==', 48 score: 2.8268959522247314 49 }, 50 { 51 title: 'The War', 52 released: ISODate('2007-09-23T00:00:00.000Z'), 53 paginationToken: 'CP9xGgYQuq+ngwgaCSkA1KkvFQEAAA==', 54 score: 2.8268959522247314 55 }, 56 { 57 title: "Hart's War", 58 released: ISODate('2002-02-15T00:00:00.000Z'), 59 paginationToken: 'CMtJGgYQuq+ngwgaCSkAjBYH7AAAAA==', 60 score: 2.8268959522247314 61 } 62 ]
Para a query anterior, observe que os resultados do Atlas Search estão em ordem inversa. A seguinte query utiliza o estágio $limit
com os métodos toArray() e reverse()
para construir uma função semelhante a "Página anterior".
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "text": { 5 "path": "title", 6 "query": "war" 7 }, 8 "sort": {score: {$meta: "searchScore"}, "released": 1}, 9 "searchBefore": "CJ6kARoGELqvp4MIGgkpACDA3U8BAAA=" 10 } 11 }, 12 { 13 "$limit": 10 14 }, 15 { 16 "$project": { 17 "_id": 0, 18 "title": 1, 19 "released": 1, 20 "paginationToken" : { "$meta" : "searchSequenceToken" }, 21 "score": { "$meta": "searchScore" } 22 } 23 } 24 ]).toArray().reverse()
1 [ 2 { 3 title: "Hart's War", 4 released: ISODate('2002-02-15T00:00:00.000Z'), 5 paginationToken: 'CMtJGgYQuq+ngwgaCSkAjBYH7AAAAA==', 6 score: 2.8268959522247314 7 }, 8 { 9 title: 'The War', 10 released: ISODate('2007-09-23T00:00:00.000Z'), 11 paginationToken: 'CP9xGgYQuq+ngwgaCSkA1KkvFQEAAA==', 12 score: 2.8268959522247314 13 }, 14 { 15 title: 'War, Inc.', 16 released: ISODate('2008-06-13T00:00:00.000Z'), 17 paginationToken: 'COhuGgYQuq+ngwgaCSkAtDh/GgEAAA==', 18 score: 2.8268959522247314 19 }, 20 { 21 title: 'War, Inc.', 22 released: ISODate('2008-06-13T00:00:00.000Z'), 23 paginationToken: 'COluGgYQuq+ngwgaCSkAtDh/GgEAAA==', 24 score: 2.8268959522247314 25 }, 26 { 27 title: 'War Dance', 28 released: ISODate('2008-11-01T00:00:00.000Z'), 29 paginationToken: 'CONvGgYQuq+ngwgaCSkAYFlVHQEAAA==', 30 score: 2.8268959522247314 31 }, 32 { 33 title: 'War Horse', 34 released: ISODate('2011-12-25T00:00:00.000Z'), 35 paginationToken: 'CJWFARoGELqvp4MIGgkpAEyEcjQBAAA=', 36 score: 2.8268959522247314 37 }, 38 { 39 title: 'Cold War', 40 released: ISODate('2012-11-08T00:00:00.000Z'), 41 paginationToken: 'CJGUARoGELqvp4MIGgkpAPBQ3ToBAAA=', 42 score: 2.8268959522247314 43 }, 44 { 45 title: 'Drug War', 46 released: ISODate('2013-04-04T00:00:00.000Z'), 47 paginationToken: 'CMWTARoGELqvp4MIGgkpAMRX0j0BAAA=', 48 score: 2.8268959522247314 49 }, 50 { 51 title: 'War Story', 52 released: ISODate('2014-07-30T00:00:00.000Z'), 53 paginationToken: 'CJCdARoGELqvp4MIGgkpAPyQhEcBAAA=', 54 score: 2.8268959522247314 55 }, 56 { 57 title: 'A War', 58 released: ISODate('2015-09-10T00:00:00.000Z'), 59 paginationToken: 'CL2kARoGELqvp4MIGgkpAECNtE8BAAA=', 60 score: 2.8268959522247314 61 } 62 ]