Как получить две коллекции в одном документе в MongoDb в С#?

Допустим, у меня есть две коллекции с именами CollectionA и CollectionB. Обе коллекции имеют разные поля. CollectionA будет иметь несколько документов с одним и тем же полем, CollectionB содержит только один документ

Пример

CollectionA
    {
       "UniqeId" :1,
       "Hobbies" : "Eating"
    },
    {
       "UniqeId" :2,
       "Hobbies" : "Sleeping"
    },
    {
       "UniqeId" :3,
       "Hobbies" : "Walking"
    }


CollectionB
    {
       "UserName" :"Sukuna",
       "UserType" : "Villan"
    }

Я хочу, чтобы вывод был таким

{
   "UniqeId" :1,
   "Hobbies" : "Eating",
   "UserName" :"Sukuna",
   "UserType" : "Villan"
}

Учтите, что все документы в CollectionA будут содержать одинаковые поля. И вы можете видеть, что между двумя коллекциями нет уникальных полей, и вы можете видеть, что нам нужно применить фильтр в CollectionA. т.е.) UniqeId=1

Я использую С#, и я могу сделать два запроса БД, чтобы получить эти сведения о коллекции (один запрос для вывода CollectionA и другой для вывода CollectionB), и мне удается объединить оба на уровне API, чтобы получить желаемый результат, но я хочу сделать на самом уровне БД,

Мне не нужны два вызова БД, которые снижают производительность API, так можно ли в любом случае добиться этого за один вызов БД или с помощью любого агрегатного конвейера? Заранее спасибо

Итак, если бы у вас было две записи в CollectionA, то вы бы ожидали 2 результата, оба с Sukuna/Villain? И если бы у вас было два целых в CollectionA и CollectionB, вы бы ожидали 4 результата (комбинация первых элементов, первого и второго, второго и первого, а затем второго и второго из двух коллекций соответственно)?

ProgrammingLlama 22.11.2022 10:05

@ProgrammingLlama Нет, я просто хочу, чтобы все поля в обеих коллекциях были в одном документе, этот единственный документ будет содержать все поля из обеих коллекций. Допустим, в CollectionA есть 2 поля, а в CollectionB — 2 поля. Выходная коллекция будет содержат 4 поля. Надеюсь, это прояснится, и я также добавил точный пример

Thiru 22.11.2022 10:12

Итак, если у вас есть 2 документа в каждой коллекции, вы просто хотите объединить все поля из всех документов в обеих коллекциях в один документ?

ProgrammingLlama 22.11.2022 10:14

Обратите внимание, что коллекция содержит документы, и не все документы должны содержать одни и те же поля, даже в одной коллекции. Также обратите внимание, что результаты, которые вы получаете от запроса, являются документами — вы не создаете новую коллекцию.

ProgrammingLlama 22.11.2022 10:15

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

Thiru 22.11.2022 10:25

Итак, вы ожидаете 3 таких результата, как это? Или, по крайней мере, это то, что в конечном итоге будет получено для запроса Id = 1, затем Id = 2, затем Id = 3?

ProgrammingLlama 22.11.2022 10:27
[{"UniqueId":1,"Hobbies":"Eating","UserName":"Sukuna","UserT‌​ype":"Villain"},{"Un‌​iqueId":2,"Hobbies":‌​"Sleeping","UserName‌​":"Sukuna","UserType‌​":"Villain"},{"Uniqu‌​eId":3,"Hobbies":"Wa‌​lking","UserName":"S‌​ukuna","UserType":"V‌​illain"}] (при условии, что вы запросили каждый из них, а затем поместили его в список). Это правильно?
ProgrammingLlama 22.11.2022 10:30

@ProgrammingLlama В коллекции A я применю фильтр, чтобы получить один документ, а в CollectionB будет только один документ, мне нужно объединить результат документа CollectionB с отфильтрованным документом CollectionA

Thiru 22.11.2022 10:33

Так это "да", верно? ХОРОШО.

ProgrammingLlama 22.11.2022 10:33

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

Thiru 22.11.2022 10:34

Извините, у меня сейчас нет времени, но вам, вероятно, понадобится $lookup с конвейером, чтобы это сделать.

ProgrammingLlama 22.11.2022 10:47

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

Thiru 22.11.2022 10:51

С одной стороны, вы говорите, что вам не нужны два запроса, но тогда вы, похоже, не хотите (IMO хакерский) способ добиться этого без двух запросов.

ProgrammingLlama 22.11.2022 11:50

Привет, позвольте мне прояснить здесь, я не хочу два вызова БД, я хочу требуемый результат в одном вызове БД, поэтому, если для этого есть один запрос, это очень ценится, и я считаю, что нам нужно общее поле в двух коллекции для выполнения поиска. К сожалению, в этом случае нет общего поля

Thiru 22.11.2022 15:25

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

ProgrammingLlama 23.11.2022 06:23

Да, я могу сделать это с помощью unionWidth и group, и ЮТинг в любом случае опубликовал ответ с поиском. Спасибо.

Thiru 23.11.2022 20:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
16
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

поиск с помощью localField 1 и ForeignField 1

db.a.aggregate([
  {
    $lookup: {
      from: "b",
      localField: "1",
      foreignField: "1",
      as: "docs"
    }
  },
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          "$$ROOT",
          { $first: "$docs" }
        ]
      }
    }
  },
  {
    $unset: [ "docs", "_id" ]
  },
  {
    $group: {
      _id: "$UserName",
      doc: { $first: "$$ROOT" }
    }
  },
  {
    $replaceWith: "$doc"
  }
])

монгоплейграунд

Спасибо, я могу сделать это с помощью unionWith и группы, и я также опубликовал решение здесь, однако я отмечу это как принятое решение. Если вы знаете какие-либо преимущества использования поиска по сравнению с unionWith и группой (например, в производительности), пожалуйста поделитесь своими мыслями. Это будет полезно для других.

Thiru 23.11.2022 20:08

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

var pipeline1= new BsonDocument("$unionWith", 
    new BsonDocument
        {
            { "coll", "CollectionB" }, 
            { "pipeline", 
    new BsonArray
            {
                new BsonDocument("$match", 
                new BsonDocument("UniqeId", 1))
            } }
        });

var pipeline2 = new BsonDocument("$group", 
    new BsonDocument
        {
            { "_id", 0 }, 
            { "merged", 
    new BsonDocument("$push", "$$ROOT") }
        });

var pipeline3 = new BsonDocument("$replaceRoot", 
    new BsonDocument("newRoot", 
    new BsonDocument("$mergeObjects", "$merged")));

var pipeline4 = new BsonDocument("$project", 
    new BsonDocument("_id", 0));


BsonDocument[] pipeline = new BsonDocument[] { pipeline1, pipeline2, pipeline3, pipeline4 };

var dbResponse = await collection.Aggregate<BsonDocument>(pipeline).ToListAsync();

Другие вопросы по теме