Как создать индекс MongoDB MultiKey на атрибуте элементов в array.NET драйвер
у меня есть коллекция MongoDB "foos", содержащая элементы, каждый из которых имеет массив"баров". То есть "foo" имеет следующую схему:
{
"id": UUID
"name": string
...
"bars": [
"id": UUID
"key": string
...
]
}
мне нужно создать индекс на имя и бар.ключ с помощью драйвера MongoDB C# .NET Mongo.
я предположил, что могу использовать функцию Linq Select для этого следующим образом:
Indexes.Add(Context.Collection<FooDocument>().Indexes.CreateOne(
Builders<FooDocument>.IndexKeys
.Descending(x => x.Bars.Select(y => y.Key))));
однако это приводит к InvalidOperationException:
система.InvalidOperationException: 'невозможно определите информацию о сериализации для x => x.Бары.Выберите (y => y.Id).'
документация Монго на MultiKey индексы показывает, как создать такой индекс, используя простую точечную нотацию, т. е.
db.foos.createIndex( { "name": 1, "bars.key": 1 } )
документация по драйверу MongoDB похоже, что использование функции Linq, как я делаю, правильно.
как создать многоключевой индекс в моей коллекции с помощью драйвера MongoDB .NET, предпочтительно использовать функцию Linq?
3 ответов
это пример того, как это сделать с C#
var indexDefinition = Builders<FooDocument>.IndexKeys.Combine(
Builders<FooDocument>.IndexKeys.Ascending(f => f.Key1),
Builders<FooDocument>.IndexKeys.Ascending(f => f.Key2));
await collection.Indexes.CreateOneAsync(indexDefinition);
обновление
что касается индекса в массиве, ближе всего, что я смог найти, это использовать "-1" в качестве индекса, когда вы строите свой ключ индекса. Как я понимаю из исходного кода github, это допустимый вариант в случае построения запросов.
var indexDefinition = Builders<FooDocument>.IndexKeys.Combine(
Builders<FooDocument>.IndexKeys.Ascending(f => f.Key1),
Builders<FooDocument>.IndexKeys.Ascending(f => f.Key2[-1].Key));
await collection.Indexes.CreateOneAsync(indexDefinition);
" -1 "- жестко закодированная константа в боковых драйверах mongodb C#, что означает"$" (доказательство). Таким образом, этот код попытается создать индекс:
{ "Key1": 1, "Key2.$.Key": 1 }
что прекрасно для запроса информации из базы данных, но не разрешено (будет выдавать исключение "ключ индекса содержит незаконное имя поля: имя поля начинается с"$"") для использования в индексах. Поэтому я предполагаю, что он должен быть изменен в драйверах mongodb, чтобы он работал. Что-то вроде "-2" означает пустой оператор. В этом случае мы могли бы использовать
var indexDefinition = Builders<FooDocument>.IndexKeys.Combine(
Builders<FooDocument>.IndexKeys.Ascending(f => f.Key1),
Builders<FooDocument>.IndexKeys.Ascending(f => f.Key2[-2].Key));
await collection.Indexes.CreateOneAsync(indexDefinition);
который будет генерировать индекс, например:
{ "Key1": 1, "Key2.Key": 1 }
поэтому в основном я не думаю, что это возможно прямо сейчас построить индекс вы хотите с чистым Linq без изменения драйверов mongo C#.
поэтому я думаю, что ваш единственный вариант сделать это, все еще C#, но без Linq
await collection.Indexes.CreateOneAsync(new BsonDocument {{"name", 1}, {"bars.key", 1}});
Вы можете создать индекс строки и использовать nameof()
в C# 6:
Indexes.Add(Context.Collection<FooDocument>().Indexes.CreateOne($"{nameof(FooDocument.Bars)}.{nameof(Bars.Key)}"));
Это запрошенная функция для драйвера C#, хотя он не видел никакого прогресса. Тем не менее, кто-то представил грубое и готовое решение там на потоке JIRA, так что, возможно, это сделает работу за вас.