Tengo una colección llamada article_category que almacenar todos los article_id pertenece a la categoría con category_id con formato de datos como tal.

Colección 1: article_category

{
  "article_id": 2015110920343902,
  "all_category_id": [5,8,10]
}

Luego tengo otra colección llamada article que almacenar todos mis post

Colección 2: artículo

{
  "title": "This is example rows in article collection"
  "article_id": 2015110920343902,
},
{
  "title": "Something change"
  "article_id": 2015110920343903,
},
{
  "title": "This is another rows",
  "article_id": 2015110920343904,
}

Ahora quiero realizar MongoDB consulta para encontrar title con regex mientras category_id debe ser igual a 8. Aquí está mi pregunta, pero no es un trabajo.

db.article.aggregate(
{
  $match: 
  {
    title: 
    {
       $regex: /example/
    }
  }
},
{
    $lookup:
       {
         from: "article_category",
         pipeline: [
            { $match: { category_id: 8 } }
         ],
         as: "article_category"
       }
  }
)

Consulta anterior sólo se muestran los registros que coinciden por regex pero no encuentro por category_id.

Alguna idea?

InformationsquelleAutor vietnguyen09 | 2018-01-30

2 Comentarios

  1. 15

    Primero de todo, es all_category_id, no category_id. En segundo lugar, que no se vinculan de artículos – todos los documentos tendrán exactamente el mismo article_category matriz. Por último, es probable que desee filtrar los artículos que no se han igualado categoría. El condicional de la tubería debe verse más como este:

    db.article.aggregate([
      { $match: {
          title: { $regex: /example/ }
      } },
      { $lookup: {
        from: "article_category",
        let: {
          article_id: "$article_id"
        },
        pipeline: [
          { $match: {
              $expr: { $and: [
                  { $in: [ 8, "$all_category_id" ] },
                  { $eq: [ "$article_id", "$$article_id" ] }
              ] }
          } }
        ],
        as: "article_category"
      } },
      { $match: {
        $expr: { $gt: [
          { $size: "$article_category"},
          0
        ] }
      } }
    ] )

    ACTUALIZACIÓN:

    Si no coinciden article_id, el $lookup con el resultado de idéntica article_category de la matriz de todos los artículos.

    Digamos que su article_category colección tiene otro documento:

    {
      "article_id": 0,
      "all_category_id": [5,8,10]
    }

    Con { $eq: [ "$article_id", "$$article_id" ] } en la canalización de la resultante article_category es

    [ 
      { 
        "article_id" : 2015110920343902, 
        "all_category_id" : [ 5, 8, 10 ] 
      } 
    ]

    sin:

    [ 
      { 
        "article_id" : 2015110920343902, 
        "all_category_id" : [ 5, 8, 10 ] 
      },
      {
        "article_id": 0,
        "all_category_id": [ 5, 8, 10 ]
      }
    ]

    Si la tarde es lo que usted necesita, sería la manera más simple de hacer para encontrar solicitudes:

    db.article.find({ title: { $regex: /example/ } })

    y

    db.article_category.find({ all_category_id: 8 })
    • No entiendo por qué se compara article_id, solo me falta la consulta de donde title se contiene sample Y article_category.all_category_id es igual a 8
    • porque and implica que debe coincidir. ver la actualización.
    • Su consulta es perfecto y funciona como un encanto, pero me tomó 26s para obtener el resultado. He estado añadiendo el índice de article_id y all_category_id pero no hubo suerte. Podría usted me sugieren cómo hacerlo más rápido? He añadido un límite de 10 pero todavía tardó 3 por resultado
    • Trate de Veeram uno. Usted realmente no necesita condicional de búsqueda aquí. Sólo se mantiene porque se le pide explícitamente cómo utilizar condicional de búsqueda en su caso. Creo que la expresión es lo que se lleva la mayor parte del tiempo, pero a decir seguro que usted necesita para proporcionar salida de explain comando con allPlansExecution opción.
  2. 2

    Has par de cosas incorrecto aquí. category_id debe ser all_category_id. El uso de la condición de combinación en $lookup y mover el $match fuera de $lookup etapa con $unwind para optimizado de búsqueda.

    Uso $project con la exclusión a la caída de los veía en el terreno de la respuesta final.
    Algo así como {$project:{article_category:0}}

    Intentar

    db.article.aggregate([
      {"$match":{"title":{"$regex":/example/}}},
      {"$lookup":{
        "from":"article_category",
        "localField":"article_id",
        "foreignField":"article_id",
        "as":"article_category"
      }},
      {"$unwind":"$article_category"},
      {"$match":{"article_category.all_category_id":8}}
    ])

    Para no subconsulta intentar

    db.article.aggregate([
      {"$match":{"title":{"$regex":/example/}}},
      {"$lookup":{
        "from":"article_category",
        "pipeline":[{"$match":{"all_category_id":8}}],
        "as":"categories"
      }},
      {"$match":{"categories":{"$ne":[]}}}
    ])

Dejar respuesta

Please enter your comment!
Please enter your name here