простое соединение SQL как с мангустом - PullRequest
1 голос
/ 08 января 2020

У меня есть документы и параметры, и я пытаюсь создать запрос для выбора документов, соответствующих параметрам.

document {
_id : ...,
status : ...,
type : ...,
...
}
parameter {
_id : ...,
parameter : ...,
status : ...,
type : ...,
}

Я думаю, SQL это убивает меня. Как мне это сделать:

select document.* from document,parameter 
  where document.type = parameter.type and document.status = parameter.status
         and parameter.parameter="example"

Возможно, я не думаю, что это правильный путь, например: я не использую какую-либо ссылочную ссылку между обоими объектами, я мог бы, но это будет ссылка N на N и Я не думаю, что это будет легко поддерживать, так как параметр или документ будут обновлены.

Ответы [ 2 ]

0 голосов
/ 08 января 2020

Пожалуйста, попробуйте следующий запрос:

db.document.aggregate([
   {
      $lookup:
         {
           from: "parameter",
           let: { type: "$type", status: "$status" },
           pipeline: [
              { $match:
                 { $expr:
                    { $and:
                       [
                         { $eq: [ "$parameter",  "example" ] },
                         { $eq: [ "$type",  "$$type" ] },
                         { $eq: [ "$status", "$$status" ] }
                       ]
                    }
                 }
              }
           ],
           as: "documentParameterJoined"
         }
    }
])

Данные сбора документов:

/* 1 */
{
    "_id" : ObjectId("5e160929627ef782360f69aa"),
    "status" : "mystatus",
    "type" : "whattype"
}

/* 2 */
{
    "_id" : ObjectId("5e160931627ef782360f6abb"),
    "status" : "mystatus1",
    "type" : "whattype1"
}

Данные сбора параметров:

/* 1 */
{
    "_id" : ObjectId("5e16095f627ef782360f6e1d"),
    "parameter" : "example",
    "status" : "mystatus",
    "type" : "whattype"
}

/* 2 */
{
    "_id" : ObjectId("5e16097e627ef782360f70b5"),
    "parameter" : "example",
    "status" : "mystatus1",
    "type" : "whattype1"
}

/* 3 */
{
    "_id" : ObjectId("5e160985627ef782360f7152"),
    "parameter" : "example1",
    "status" : "mystatus",
    "type" : "whatType"
}

/* 4 */
{
    "_id" : ObjectId("5e160a39627ef782360f8027"),
    "parameter" : "example",
    "status" : "mystatus1",
    "type" : "whatType"
}

/* 5 */
{
    "_id" : ObjectId("5e160a42627ef782360f80ec"),
    "parameter" : "example",
    "status" : "mystatus",
    "type" : "whatType1"
}

Результат:

 // You don't see docs 3 to 5 as they don't match any filter criteria.
/* 1 */
{
    "_id" : ObjectId("5e160929627ef782360f69aa"),
    "status" : "mystatus",
    "type" : "whattype",
    "documentParameterJoined" : [ 
        {
            "_id" : ObjectId("5e16095f627ef782360f6e1d"),
            "parameter" : "example",
            "status" : "mystatus",
            "type" : "whattype"
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("5e160931627ef782360f6abb"),
    "status" : "mystatus1",
    "type" : "whattype1",
    "documentParameterJoined" : [ 
        {
            "_id" : ObjectId("5e16097e627ef782360f70b5"),
            "parameter" : "example",
            "status" : "mystatus1",
            "type" : "whattype1"
        }
    ]
}

Вам не нужно делать два вызова в БД, вы можете использовать $lookup (который является родным для mongoDB) с выражением для достижения что нужно Также вы можете попробовать подобное, используя mongoose populate (который является своего рода оболочкой для mongoDB $lookup)

Ref: $ lookup , mon goose -populate

0 голосов
/ 08 января 2020

Я придумала это с ошибкой, но я все еще открыта для предложения.

parameter.find({parameter :"example"}, function(err, parameters){
  var parameters_status;
  var parameters_type;

  if (err) {
    // do error handling
    return;
  }

  parameters_status= parameters.map(function (parameters) { return parameters.status; });
  parameters_type= parameters.map(function (parameters) { return parameters.type; });

  document.find({type: {$in: parameters_type},status : {$in: parameters_status} }, function (err, documents) {
    if (err) {
      // do error handling
      return;
    }

    console.log(documents);
    // do something with the documents
  });
});
...