Как получить все встроенные элементы в коллекции документов?

1

Я застрял в этой проблеме уже пару дней. Я пытаюсь сделать следующее:

Рассмотрим следующие классы С#, соответствующие документам в MongoDB. Торговцы хранятся в коллекции торговцев, и все они содержат массив валют.

class Merchant
{
    public string id {get;set;}
    public List<Currency> MerchantCurrencies {get; set; }
}

class Currency
{
    public string id {get; set; }
    public string name {get; set; }
    ...
}

Теперь, что я хочу сделать, нужно вернуть все валюты всех продавцов в рамках одного запроса с LINQ. Я пробовал такие вещи, как SelectMany и несколько из предложений, например:

var currencies = merchantCollection.AsQueryable()
.SelectMany(m => m.MerchantCurrencies)
.Where(ccy => ccy.CurrencyState == currencyStatus)
.OrderBy(ccy => ccy.CurrencyName);

а также

var currencies= from merch in merchantCollection.AsQueryable()
from ccy in merch.MerchantCurrencies
select ccy

Однако все эти вещи не работают, поскольку они основаны на SelectMany, который использует объединения. Использование SelectMany вызовет исключение, поскольку оно не поддерживается драйвером MongoDB С#.

Есть ли какое-либо решение моей проблемы, помимо использования структуры агрегации/сокращения карты/нескольких запросов?

Единственное решение, которое я нашел, было:
1. Получение всех купцов
2. Прокрутите торговцев
3. Перемещайтесь по их валютам
4. Добавьте валюты в другую переменную списка

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

С уважением

Теги:
linq

2 ответа

0

Отказ от ответственности: я знаю 0 о С# и LINQ

Тем не менее, есть встроенная функция для выполнения того, что вы хотите: distinct. За отказ от ответственности я проиллюстрирую в оболочке монго:

> db.test.drop()
> db.test.insert({ "a" : [{ "a" :1 , "b" : 2 }, "op", 2, "3", "goop"] })
> db.test.insert({ "a" : [1,2, 3, "goop"] })
> db.test.distinct("a")
[ 1, 2, 3, "goop", "3", "op", { "a" : 1, "b" : 2 } ]
> db.test.distinct("a", { "a" : "op" })
[ 2, "3", "goop", "op", { "a" : 1, "b" : 2 } ]

Он делает ваши 1-4, но на стороне сервера, по существу - другого способа получить отдельные значения документов, кроме тех случаев, когда работа уже частично выполнена, потому что там индекс, не может быть другого способа. Если у вас есть индекс в { "a": 1 } в приведенном выше примере, distinct могут использовать это, чтобы найти различные значения с помощью сканирования индекса вместо сканирования коллекции.

Я думаю, что С# метод, который вы хотите, это один.

  • 0
    Ваш ответ кажется правдоподобным, но знаете ли вы, как еще уменьшить результаты? Мол, когда вы получаете отличия, я хочу еще больше сузить элементы, например. запрашивая их по имени. Ты знаешь как это сделать? Так что-то вроде db.merchants.distinct ("merchantcurrencies"). Find ({"name: <term>});
0

Кажется, вы пытаетесь использовать базу данных NoSQL для хранения реляционных данных, что может быть не очень хорошая идея. Если вы хотите придерживаться MongoDB, я бы рекомендовал добавить новую коллекцию всех разных валют и обновить ее по мере необходимости.

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

MongoDB не поддерживает объединения, и поэтому время от времени требуется бит денормализации. Коллекции MongoDB не эквивалентны реляционным таблицам; каждая из которых служит уникальной проектной цели. Нормализованная таблица обеспечивает атомный изолированный кусок данных. Однако документ более тесно представляет собой объект в целом.

  • 0
    Здравствуйте, спасибо за ваш ответ, но, к сожалению, это не сработает. Внутренняя реализация SelectMany использует объединения для объединения нескольких таблиц. Объединения не существуют в MongoDB. Использование SelectMany, таким образом, вызовет исключение при использовании. Я уже пробовал это.
  • 0
    Извините, я пропустил часть о вашем вопросе, который касался объединений в MongoDB. Я отредактировал свой ответ соответственно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню