Mon go DB Как найти общее в двух массивах и отсортировать по убыванию в одном запросе - PullRequest
0 голосов
/ 27 марта 2020

Здесь мои данные сохраняются в базе данных

0  _id:5e4d18bd10e5482eb623c6e4
   name:'John singh',
   cars_owned:[
       {car_id:'1'},
       {car_id:'5'},
       {car_id:'7'},
       {car_id:'8'}
   ],

1  _id:5e4d18bd10e5482eb6g57f5rt
   name:'Josh kumar',
   cars_owned:[
       {car_id:'7'},
       {car_id:'9'},
       {car_id:'1'},
       {car_id:'3'}
   ],

2  _id:5e4d18bd10e5482eb6r67222
   name:'Jesse nigam',
   cars_owned:[
       {car_id:'6'},
       {car_id:'7'},
       {car_id:'9'},
       {car_id:'3'}
   ],

3  _id:5e4d18bd10e5482eb6467ii46
   name:'Jordan khan',
   cars_owned:[
       {car_id:'3'},
       {car_id:'1'},
       {car_id:'4'},
       {car_id:'5'}
   ]

Теперь я хочу найти пользователя с его начальным именем 'J', а также cars_owned мной, ввод будет

  'J',cars_owned['3','7','9','12','10']

, и результат будет

   1  _id:5e4d18bd10e5482eb6g57f5rt
   name:'Josh kumar',
   cars_owned:[
       {car_id:'7'},
       {car_id:'9'},
       {car_id:'1'},
       {car_id:'3'}
   ],

   2  _id:5e4d18bd10e5482eb6r67222
   name:'Jesse nigam',
   cars_owned:[
       {car_id:'6'},
       {car_id:'7'},
       {car_id:'9'},
       {car_id:'3'}
   ],

   0  _id:5e4d18bd10e5482eb623c6e4
   name:'John singh',
   cars_owned:[
       {car_id:'1'},
       {car_id:'5'},
       {car_id:'7'},
       {car_id:'8'}
   ],

   3  _id:5e4d18bd10e5482eb6467ii46
   name:'Jordan khan',
   cars_owned:[
       {car_id:'3'},
       {car_id:'1'},
       {car_id:'4'},
       {car_id:'5'}
   ]

, и теперь вы заметите, что результатом будут все пользователи, чье имя начинается с 'J', а cars_owned - в 3,7,9,12, 10 , но в порядке убывания, то есть пользователь, которому соответствует большинство cars_owned и другие. Я хочу, чтобы результат сортировался в соответствии с максимальным значением cars_owned в одном запросе mon go db . До сих пор я сделал один простой запрос поиска.

  User_data.find({name: { $regex: "^" + search_name },
                  cars_owned:{$elemMatch:{car_id:'3',car_id:'7',car_id:'9',car_id:'12',car_id:'10'} 
                 }},function(err,resp){

                      console.log(JSON.stringify(resp,null,4));

          });

, но он возвращает только один документ. Я хочу, чтобы все документы имели какой-либо из указанных данных car_id, но отсортированы по максимальному соответствию. Если вы ничего не понимаете в этом вопросе, не стесняйтесь спрашивать в комментариях, но, пожалуйста, дайте ответ в одном запросе mon go db. Я также согласен со структурой агрегирования. Заранее спасибо.

1 Ответ

1 голос
/ 27 марта 2020

Вы должны использовать агрегацию для этого. Сначала вы определяете, сколько автомобилей пользователя являются общими с вашим списком, затем фильтруете результаты, соответствующие названию и хотя бы одной общей машине, и, наконец, сортируете результаты по общим машинам.

Вот запрос:

db.collection.aggregate([
  {
    $addFields: {
      commonCars: {
        $size: {
          $setIntersection: [
            [
              "3",
              "7",
              "9",
              "12",
              "10"
            ],
            "$cars_owned.car_id"
          ]
        },

      }
    }
  },
  {
    $match: {
      $expr: {
        $and: [
          {
            $eq: [
              {
                $regexMatch: {
                  input: "$name",
                  regex: "^J"
                }
              },
              true
            ]
          },
          {
            $gt: [
              "$commonCars",
              0
            ]
          }
        ]
      }
    }
  },
  {
    $sort: {
      "commonCars": -1
    }
  }
])

И вы можете проверить это здесь


РЕДАКТИРОВАТЬ

если вам не нужно сортировать свой результат, вы можете достичь этого в одном матче stage:

db.collection.aggregate([
  {
    $match: {
      $expr: {
        $and: [
          {
            $eq: [
              {
                $regexMatch: {
                  input: "$name",
                  regex: "^J"
                }
              },
              true
            ]
          },
          {
            $gt: [
              {
                $size: {
                  $setIntersection: [
                    [
                      "3",
                      "7",
                      "9",
                      "12",
                      "10"
                    ],
                    "$cars_owned.car_id"
                  ]
                },

              },
              0
            ]
          }
        ]
      }
    }
  },

])

Проверьте это здесь

...