如何在 C# Mongodb 强类型驱动程序中基于嵌套数组元素创建索引
How to create index based on nested array element in C# Mongodb strongly typed driver
这个问题与 的原则完全相同,但我想在 object 属性 上使用强类型方法创建索引,当此 object 嵌套在 collection.
的数组中
我可以使用:
new CreateIndexModel<T>( Builders<T>.IndexKeys.Ascending( a ) )
其中 a 是一个直接访问 属性.
的表达式
但我没有发现类似的内容:
Builders<Library>.Filter.ElemMatch(x => x.Author.Books, b => b.IsVerified == false));
这样我就可以将嵌套在数组中的 object 的某个字段定义为索引,该数组是 collection.
的成员
这可能吗?怎么做?
考虑以下数据模型:
public class Course
{
public string Name { get; set; }
public string Teacher { get; set; }
}
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public ReadOnlyCollection<Course> Courses { get; set; }
}
您可以通过以下方式在字段 Courses 上创建升序多键索引:
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public static class Program
{
private static MongoClient Client;
private static IMongoDatabase Database;
private static IMongoCollection<Student> Collection;
public static async Task Main(string[] args)
{
Client = new MongoClient();
Database = Client.GetDatabase("test-index");
Collection = Database.GetCollection<Student>("students");
var courses1 = new List<Course>()
{
new Course { Name = "Math", Teacher = "Bob" }
}.AsReadOnly();
var courses2 = new List<Course>()
{
new Course { Name = "Computer Science", Teacher = "Alice" }
}.AsReadOnly();
var mark = new Student
{
Name = "Mark",
Courses = courses1,
Age = 20
};
var lucas = new Student
{
Name = "Lucas",
Courses = courses2,
Age = 22
};
await Collection.InsertManyAsync(new[] { mark, lucas }).ConfigureAwait(false);
var model = new CreateIndexModel<Student>(
Builders<Student>.IndexKeys.Ascending(s => s.Courses));
await Collection.Indexes.CreateOneAsync(model).ConfigureAwait(false);
Console.WriteLine("All done !");
}
}
}
此查询由您创建的索引提供服务:
db.students.find({Courses: {"Name": "Math", "Teacher": "Bob"}})
如果您不想在整个数组 Courses 上创建索引,而是想在嵌套对象(Course 对象)的字段 Name 上创建索引,这是方法:
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public static class Program
{
private static MongoClient Client;
private static IMongoDatabase Database;
private static IMongoCollection<Student> Collection;
public static async Task Main(string[] args)
{
Client = new MongoClient();
Database = Client.GetDatabase("test-index");
Collection = Database.GetCollection<Student>("students");
var courses1 = new List<Course>()
{
new Course { Name = "Math", Teacher = "Bob" }
}.AsReadOnly();
var courses2 = new List<Course>()
{
new Course { Name = "Computer Science", Teacher = "Alice" }
}.AsReadOnly();
var mark = new Student
{
Name = "Mark",
Courses = courses1,
Age = 20
};
var lucas = new Student
{
Name = "Lucas",
Courses = courses2,
Age = 22
};
await Collection.InsertManyAsync(new[] { mark, lucas }).ConfigureAwait(false);
var model = new CreateIndexModel<Student>(
Builders<Student>.IndexKeys.Ascending("Courses.Name"));
await Collection.Indexes.CreateOneAsync(model).ConfigureAwait(false);
Console.WriteLine("All done !");
}
}
}
此查询由您创建的索引提供服务:db.students.explain("executionStats").find({"Courses.Name": "Math"})
在我的第二个示例中避免使用魔术字符串的一种可能方法是利用 nameof C# 运算符的强大功能:
$"{nameof(Student.Courses)}.{nameof(Course.Name)}"
这是使用 MongoDB.Entities 便利库为嵌套字段创建索引的强类型方法。 [免责声明:我是作者]
using MongoDB.Entities;
using System.Collections.Generic;
namespace Whosebug
{
public class Program
{
public class Parent : Entity
{
public Child[] Children { get; set; }
}
public class Child
{
public List<Friend> Friends { get; set; }
}
public class Friend
{
public string Name { get; set; }
}
static void Main(string[] args)
{
new DB("test");
DB.Index<Parent>()
.Key(p => p.Children[-1].Friends[-1].Name, KeyType.Ascending)
.Create();
}
}
}
上面使用以下命令在嵌套两层的名称字段上创建升序索引:
db.Parent.createIndex({
"Children.Friends.Name": NumberInt("1")
}, {
name: "Children.Friends.Name(Asc)",
background: true
})
这个问题与
我可以使用:
new CreateIndexModel<T>( Builders<T>.IndexKeys.Ascending( a ) )
其中 a 是一个直接访问 属性.
的表达式但我没有发现类似的内容:
Builders<Library>.Filter.ElemMatch(x => x.Author.Books, b => b.IsVerified == false));
这样我就可以将嵌套在数组中的 object 的某个字段定义为索引,该数组是 collection.
的成员这可能吗?怎么做?
考虑以下数据模型:
public class Course
{
public string Name { get; set; }
public string Teacher { get; set; }
}
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public ReadOnlyCollection<Course> Courses { get; set; }
}
您可以通过以下方式在字段 Courses 上创建升序多键索引:
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public static class Program
{
private static MongoClient Client;
private static IMongoDatabase Database;
private static IMongoCollection<Student> Collection;
public static async Task Main(string[] args)
{
Client = new MongoClient();
Database = Client.GetDatabase("test-index");
Collection = Database.GetCollection<Student>("students");
var courses1 = new List<Course>()
{
new Course { Name = "Math", Teacher = "Bob" }
}.AsReadOnly();
var courses2 = new List<Course>()
{
new Course { Name = "Computer Science", Teacher = "Alice" }
}.AsReadOnly();
var mark = new Student
{
Name = "Mark",
Courses = courses1,
Age = 20
};
var lucas = new Student
{
Name = "Lucas",
Courses = courses2,
Age = 22
};
await Collection.InsertManyAsync(new[] { mark, lucas }).ConfigureAwait(false);
var model = new CreateIndexModel<Student>(
Builders<Student>.IndexKeys.Ascending(s => s.Courses));
await Collection.Indexes.CreateOneAsync(model).ConfigureAwait(false);
Console.WriteLine("All done !");
}
}
}
此查询由您创建的索引提供服务:
db.students.find({Courses: {"Name": "Math", "Teacher": "Bob"}})
如果您不想在整个数组 Courses 上创建索引,而是想在嵌套对象(Course 对象)的字段 Name 上创建索引,这是方法:
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public static class Program
{
private static MongoClient Client;
private static IMongoDatabase Database;
private static IMongoCollection<Student> Collection;
public static async Task Main(string[] args)
{
Client = new MongoClient();
Database = Client.GetDatabase("test-index");
Collection = Database.GetCollection<Student>("students");
var courses1 = new List<Course>()
{
new Course { Name = "Math", Teacher = "Bob" }
}.AsReadOnly();
var courses2 = new List<Course>()
{
new Course { Name = "Computer Science", Teacher = "Alice" }
}.AsReadOnly();
var mark = new Student
{
Name = "Mark",
Courses = courses1,
Age = 20
};
var lucas = new Student
{
Name = "Lucas",
Courses = courses2,
Age = 22
};
await Collection.InsertManyAsync(new[] { mark, lucas }).ConfigureAwait(false);
var model = new CreateIndexModel<Student>(
Builders<Student>.IndexKeys.Ascending("Courses.Name"));
await Collection.Indexes.CreateOneAsync(model).ConfigureAwait(false);
Console.WriteLine("All done !");
}
}
}
此查询由您创建的索引提供服务:db.students.explain("executionStats").find({"Courses.Name": "Math"})
在我的第二个示例中避免使用魔术字符串的一种可能方法是利用 nameof C# 运算符的强大功能:
$"{nameof(Student.Courses)}.{nameof(Course.Name)}"
这是使用 MongoDB.Entities 便利库为嵌套字段创建索引的强类型方法。 [免责声明:我是作者]
using MongoDB.Entities;
using System.Collections.Generic;
namespace Whosebug
{
public class Program
{
public class Parent : Entity
{
public Child[] Children { get; set; }
}
public class Child
{
public List<Friend> Friends { get; set; }
}
public class Friend
{
public string Name { get; set; }
}
static void Main(string[] args)
{
new DB("test");
DB.Index<Parent>()
.Key(p => p.Children[-1].Friends[-1].Name, KeyType.Ascending)
.Create();
}
}
}
上面使用以下命令在嵌套两层的名称字段上创建升序索引:
db.Parent.createIndex({
"Children.Friends.Name": NumberInt("1")
}, {
name: "Children.Friends.Name(Asc)",
background: true
})