MongoTemplate Consulta de matriz que correspondam a, pelo menos, os valores que eu estou passando

0

Pergunta

Se eu tiver uma documentação definida como

[
  {
    "title": "title",
    "tags": [ "cool", "amazing", "funny" ]
  },
  {
    "title": "another title",
    "tags": [ "nice", "amazing", "funny" ]
  }
]

Eu gostaria de ser capaz de consulta com MongoTemplate, a fim de passar uma lista de valores como ["legal","incrível"] e, em retorno, a primeira coleção de cima, e não o segundo. Para o que eu quero alcançar, o $em condição não parece suficiente. Eu tentei com o $todo condição e, a partir do Mongo console funciona como eu preciso, mas no meu código que algo não está funcionando e ele leva uma eternidade para minha consulta para a elaboração. Com o $no operador meu código passa rápido, em vez disso. O meu método no meu repositório (por outras razões, eu tenho que fazer uma agregação, conforme abaixo):

public Page<MyDocument> findByProperties(String title, List<ObjectId> tags, Pageable page) {
        final List<Criteria> criteria = new ArrayList<>();
        Aggregation aggregation = null;

        
        if (title != null && !title.isEmpty()) {
            criteria.add(Criteria.where("title").is(title));
        }
        
        if (tags != null && !tags.isEmpty()) {
            criteria.add(Criteria.where("MyBook.tags").all(tags));
        }

        if (!criteria.isEmpty()) {
            aggregation = Aggregation.newAggregation(
                    Aggregation.lookup("from_collection", "_id", "idParent", "MyBook"),
                    Aggregation.unwind("MyBook"),
                    Aggregation.match(new Criteria().andOperator(criteria.toArray(new Criteria[0]))),
                    Aggregation.skip(page.getOffset()),
                    Aggregation.limit(page.getPageSize()),
                    Aggregation.sort(page.getSort())
            );
        } else {
            aggregation = Aggregation.newAggregation(
                    Aggregation.lookup("from_collection", "_id", "idParent", "MyBook"),
                    Aggregation.unwind("MyBook"),
                    Aggregation.skip(page.getOffset()),
                    Aggregation.limit(page.getPageSize()),
                    Aggregation.sort(page.getSort())
            );
        }

        List<MyDocument>  results  = mongoTemplate.aggregate(aggregation, "my_document", MyDocument.class).getMappedResults();

        return PageableExecutionUtils.getPage(results, page,
                () -> (long)results.size());
    } 

Olhando para esta resposta, eu tentei com o

criteria.add(Criteria.where("MyBook.tags").in(tags).all(tags));

Mas nada mudou, a consulta leva para sempre, e não com a saída esperada. Alguma idéia por favor? Obrigado!

1

Melhor resposta

0

Para descobrir se as tags campo de matriz contém todos os membros do seu array, você pode usar o fole, se você precisa que ele seja na agregação de pipeline usar o segundo.

Em sua consulta, você ter mais fases e mais de código, se você quiser perguntar mais se você pode dar exemplo de dados e a saída esperada em JSON, e o que você quer fazer, então as pessoas podem ajudar.

Consulta1

  • encontrar usando $all operador de

Código de teste aqui

db.collection.find({"tags": {"$all": ["cool","amazing"]}})

Query2

  • solução de agregação com o conjunto de diferença

Código de teste aqui

aggregate(
[{"$match": 
    {"$expr": 
      {"$eq": [{"$setDifference": [["cool", "amazing"], "$tags"]}, []]}}}])
2021-11-23 17:19:23

Oi Takis, obrigado por suas dicas! O que eu preciso é fazê-lo com Java, e não por meio Mongo console onde já funciona. Com MongoTemplate que eu teria que usar uma Projeção, e no meu caso, eu prefiro ficar com a Agregação. Para exemplos de código, eu só preciso juntar duas coleções (Agregação) e a consulta em uma Matriz presente na "MyBook" coleção que entro em
Barbi

Em outros idiomas

Esta página está em outros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................