Как реализовать поиск в заселённом монгодб? - PullRequest
0 голосов
/ 27 мая 2019

так что проблема продолжилась вчера , у меня снова возникла новая проблема

Я прочитал документацию, из которой я получаю правильную функцию для поиска в совокупности - использовать $match,

когда я реализовал это, я не получил нужные данные, до этого я использовал find на mongoose, и это сработало.

если агрегат может это сделать, как вы это реализуете??Заранее спасибо

 const accounts = await Account.find({
        //  query      database             query
        ...(_id    && {_id    : { $in    : _id.split(",")    }}),
        ...(name   && {$text  : { $search: name           }}),
        ...(email  && {email  : { $in    : email.split(",")  }}),
        ...(phone  && {phone  : { $in    : phone.split(",")  }}),
        ...(status && {status : { $in    : status.split(",") }}),
  });

  const newAcc = await accounts.map(async account => {
    const accMeta = await AccountMeta.find({ 
        ...({account_id        : account._id}),
        ...(ac_key   && {key   : ac_key}),
        ...(ac_value && {value : ac_value})
   });

К вашему сведению: прежде чем использовать агрегат, в приведенном выше примере я использовал объект слияния, созданный javascript, из-за ограничений в разделе account_meta, поэтому я попытался скомбинировать его для слияния

это мое объединение:

exports.get_Account = async (req, res) => {
  const { _id, name, email, phone, status, value } = req.query

  console.log(req.query)

  const result = await Account.aggregate([
    {
        $lookup      : {
            from         : "account_meta",
            localField   : "_id",
            foreignField : "account_id",
            as           : "metas"
        }
    },
    { "$unwind": "$metas" },
    {
        $group   : {
            _id      : "$_id",
            name     : {$first: "$name"     },
            status   : {$first: "$status"   },
            email    : {$first: "$email"    },
            password : {$first: "$password" },
            data     : {
            "$push"  : {
                "k"      : "$metas.key",
                "v"      : "$metas.value"
                }
            }
        }
    },
    {
        $project       : {
            "_id"          : "$_id",
            "name"         : "$name",
            "email"        : "$email",
            "status"       : "$status",
            "password"     : "$password",
            "metas"        : {
                $arrayToObject : "$data"
                    }
        }
    },
    {
        "$replaceRoot": {
            "newRoot":
                {
                    "$mergeObjects": [ "$$ROOT",'$metas']
                },
        }
    },
    {
      $match: 
      {
          $or      : [
              { value  : value  },
              { _id    : _id    },
              { email  : email  },
              { phone  : phone  },
              { status : status },
          ],
      }
    },
    {
        $project : {
            metas: 0
        }
    },

  ])
  res.json(result)
};

Добавить результат:

[
    {
        "_id": "5ce8981a46039c14a4ec32d1",
        "name": "Monkey D Luffy",
        "email": "aaa@aaa.com",
        "status": "not verified",
        "password": "$2a$10$ayluBIsOOelBTIk.69GjHubgQemr6dJfgBUELNusCOaUGLpS/qKs6",
        "role": "admin",
        "smartphone": "ios",
        "alamat": "jogja",
        "hobi": "mancing"
    },
    {
        "_id": "5ce8980b46039c14a4ec32cf",
        "name": "Monkey D Law",
        "email": "ccc@ccc.com",
        "status": "not verified",
        "password": "$2a$10$t7pqvWTzagSWCFtW.d3vnOmR.r5mgZ4jTZEx3IA1X2aeWUn/76Yq6",
        "role": "admin",
        "laptop": "asus",
        "mobil": "toyota"
    },
    {
        "_id": "5ce897fc46039c14a4ec32cd",
        "name": "Monkey D Dragon",
        "email": "ddd@ddd.com",
        "status": "not verified",
        "password": "$2a$10$5X75lGHkMydRZb6tCLgOsO0cvZZyc8z2vllTmgbpw9WKL3VGivrse",
        "role": "admin",
        "gender": "perempuan",
        "smartphone": "android"
    }
]

результаты, которые я хочу получить в двух моих случаях, одинаковы, но с методом .findи объединить объект с JavaScript Я не могу искать account_meta См. результаты роли ниже , я ищу другие методы, чтобы объединить и добиться успеха.теперь проблема заключается в реализации поиска для агрегата

: я изменяю свой метод с агрегата обратно на заполнение

exports.get_Account = async (req, res) => {
  let { _id, name, email, phone, status, value, value_else, key } = req.query 

        console.log('value type', typeof value)
        console.log('value_else type', typeof value_else)
        value         = value + '' ? value.split(',')           : value
        value_else    = value_else + '' ? value_else.split(',') : value_else
        // value_else = == undefined ? null      : ''

        console.log('value', value)
        console.log('value else', value_else)

        let orUserMeta = [], orUserMetaElse = [];

        _.forEach(value,str => {
            orUserMeta = [ ...orUserMeta, { value: str } ]
        })
        console.log('usrmeta', orUserMeta)

        _.forEach(value_else,str => {
          orUserMetaElse = [ ...orUserMetaElse, { value: str } ]
        })
        console.log('usermetaElse', orUserMetaElse)

  const accountMeta = await AccountMeta.find({

        ...(_id        && { _id }),
        ...(key        && { key }),
        ...( value     && { $or :  orUserMeta }), //failed
        ...(value_else && { $nor : orUserMetaElse }) // failed
  }).lean().populate({
    path   : 'account_id',
    select : '-password',
    match  : {
      ...(email   && { email }),
      ...(phone   && { phone }),
      ...(status  && { status }),
      ...(name    && {$text  : { $search: name }})
      }
  })


  res.json(accountMeta)
}

, и теперь моя проблема в том, что не могу найти с помощью $ or or$ или потому что я получил отдельное значение, когда я нажал в моем почтальоне ... и когда я перешел в массив, произошла ошибка split is undefined.какие-либо подсказки или советы для этого?заранее спасибо

...