Hice el siguiente filtro con la esperanza de que combinaría los resultados de las 3 matrices $and pero solo coincide con uno de esos bloques.

¿Cómo puedo combinar los resultados de lo que se devolvería de cada matriz $and si se cumplen las condiciones? Espero que eso esté claro. No sé cómo llamar a la matriz $and.

const filter = {
      $or: [
        {
          $and: [
            { category: req.query.category },
            { tags: req.query.subCategory },
            {contentType: req.query.contentType},
            req.query.searchTerm !== ""
              ? {
                  name: {
                    $regex: "(?i)" + req.query.searchTerm + "(?-i)",
                    $options: "i",
                  },
                }
              : {},
          ],
          $and: [
             { category: req.query.category },
            { tags: req.query.subCategory },
            {contentType: req.query.contentType},
            req.query.searchTerm !== ""
              ? {
                  description: {
                    $regex: "(?i)" + req.query.searchTerm + "(?-i)",
                    $options: "i",
                  },
                }
              : {},
          ],
          $and: [
             { category: req.query.category },
            { tags: req.query.subCategory },
            {contentType: req.query.contentType},
            req.query.searchTerm !== ""
              ? {
                  tags: {
                    $regex: "(?i)" + req.query.searchTerm + "(?-i)",
                    $options: "i",
                  },
                }
              : {},
          ],
        },
      ],
    };
 await Content.paginate(filter, options, (err, result) => {
      if (err) {
        res.status(500).send(err);
      } else {
        res.json(result);
      }
    });

EDITAR: a continuación se muestra un ejemplo de dos entradas que se encontrarían en la base de datos. La forma en que debería funcionar es usar category, subCategory y contentType para filtrar las entradas en la base de datos, de modo que lo que tengo ahora son solo las entradas que tienen el mismo { {X3}}, subCategory y contentType como se especifica en req.query, lo llamaré firstFilterResult. A partir de ahí, estoy intentando buscar dentro de firstFilterResult para ver si tengo entradas que tengan coincidencias name, tag o description. Básicamente, catgeory, subCategory y contentType solo se usan para reducir los resultados para que pueda encontrar coincidencias para name, tag y {{X17 }}. Mi código anterior no hace exactamente esto, pero esta es la idea detrás de esto y pensé que lo que tengo sería similar, pero supongo que estoy equivocado.

contents: [
      {
        tags: [
          'food',
          'drinks',
          'card',
          'account'
        ],
        _id: '1d13ff7m6db4d5417cd608f4',
        name: 'THE NAME FOR THIS PIECE OF CONTENT',
        description: 'In here I will begin to talk about...',
        content_id: '5dbcb998ad4144390c244093',
        contentType: 'quiz',
        date: '2019-06-03T04:00:00.000Z',
        category: 'food',
        image: 'https://IMAGE.PNG',
        __v: 0
      },
      {
        tags: [
          'computer',
          'laptop'
        ],
        _id: '7d1b940b1c9d44000025db8c',
        name: 'THE NAME FOR THIS PIECE OF CONTENT',
        description: 'This is another description',
        content_id: '5f1b963d1c9d44000055db8d',
        contentType: 'tool',
        date: '2019-06-03T04:00:00.000Z',
        category: 'money',
        image: 'https://IMAGE.PNG',
        __v: 0
      }
 ]
0
mastercool 23 jun. 2020 a las 01:35

2 respuestas

Dado que cada elemento de $or contiene los mismos 3 controles con uno solo que varía, estos se pueden separar, y el $or solo es necesario si se especifica un término de búsqueda.

Pasar options:"i" hace que la expresión regular coincida entre mayúsculas y minúsculas, por lo que no es necesario rodear la cadena de búsqueda con (?i) y (?-i)

Lo siguiente debería compilar el filtro que está intentando, sin usar objetos vacíos:

// base query that checks the common fields
var filter = {
               category: req.query.category,
               tags: req.query.subCategory,
               contentType: req.query.contentType
};

// if a search term is provided, add in the additional critera
if (req.query.searchTerm !== "") {
  var regex = {
               $regex: req.query.searchTerm, 
               options:"i"
  };
  filter['$or'] = [
       { name: regex },
       { description: regex },
       { tags: regex }
  ]
}

Si esto no obtiene los resultados que busca, edite la pregunta y agregue algunos documentos de muestra para que podamos ver el problema.

0
Joe 23 jun. 2020 a las 01:30

Finalmente llegué a trabajar con esto

 const catFilter =
      req.query.category !== "" ? { category: req.query.category } : {};
    const subCatFilter =
      req.query.subCategory !== "" ? { tags: req.query.subCategory } : {};
    const typeFilter =
      req.query.contentType !== ""
        ? { contentType: req.query.contentType }
        : {};
    const filter = {
      $and: [
        {
          $or: [
            {
              name: {
                $regex: req.query.searchTerm,
                $options: "i",
              },
            },
            {
              description: {
                $regex: req.query.searchTerm,
                $options: "i",
              },
            },
            {
              tags: {
                $regex: req.query.searchTerm,
                $options: "i",
              },
            },
          ],
        },
        catFilter,
        subCatFilter,
        typeFilter,
      ],
    };
0
mastercool 23 jun. 2020 a las 14:18