一、包含子文檔的集合操作
有這麼一個應用場景,某網站提供會員登錄的功能,用戶需要註冊賬號才能享受會員服務,但是註冊者可能會因爲用戶資料表單輸入項過大而放棄填寫,因此用戶信息分爲主要資料和詳細資料兩項,初次註冊只需要填寫主要資料就行了。我們打算把詳細信息設計爲子文檔存儲。
1) linq方式實現
1. 新建數據描述類,描述用戶信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/// <summary>
/// 用戶主要資料
/// </summary>
public
class UserInfo { public
string UserId {
get ; set ; }
public
string UserName {
get ; set ; }
public
string PassWord {
get ; set ; }
public
Detail Detail { get ;
set ; }
} /// <summary>
/// 用戶詳細資料
/// </summary>
public
class Detail
{ public
string Address {
get ; set ; }
public
int Age { get ;
set ; }
public
string Email {
get ; set ; }
} |
2. 我們要新建一個用戶業務操作類“UserBLL”。這個時候要讓驅動知道UserInfo類描述了“用戶資料”的字段信息,在GetMongo()方法實現了配置步驟,UserBLL完整代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
public
class UserBLL { public
string databaseName =
"myDatabase" ;
private
Mongo mongo; private
MongoDatabase mongoDatabase; //注意這裏泛型類型爲“UserInfo”
private
MongoCollection<UserInfo> mongoCollection; public
UserBLL() {
mongo = GetMongo();
mongoDatabase = mongo.GetDatabase(databaseName)
as MongoDatabase;
mongoCollection = mongoDatabase.GetCollection<UserInfo>()
as MongoCollection<UserInfo>;
mongo.Connect();
}
~UserBLL()
{
mongo.Disconnect();
}
/// <summary>
/// 配置Mongo,將類UserInfo映射到集合
/// </summary>
private
Mongo GetMongo() {
var config =
new MongoConfigurationBuilder();
config.Mapping(mapping =>
{
mapping.DefaultProfile(profile =>
{
profile.SubClassesAre(t => t.IsSubclassOf( typeof (UserInfo)));
});
mapping.Map<UserInfo>();
});
config.ConnectionString(connectionString);
return
new Mongo(config.BuildConfiguration());
}
} |
3. 接着,在“UserBLL”類中定義一個方法“InsertSomeData()”來插入一些數據:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
/// <summary>
/// 插入一些數據
/// </summary>
public
void InsertSomeData() { UserInfo userInfo1 =
new UserInfo()
{
UserId =
"1001" ,
UserName =
"張三" ,
PassWord =
"123456" };
mongoCollection.Save(userInfo1);
UserInfo userInfo2 =
new UserInfo()
{
UserId =
"1002" ,
UserName =
"李四" ,
PassWord =
"123456" ,
Detail =
new Detail()
{
Address =
"湖北" ,
Age = 20,
}
};
mongoCollection.Save(userInfo2);
UserInfo userInfo3 =
new UserInfo()
{
UserId =
"1003" ,
UserName =
"王五" ,
PassWord =
"123456" ,
Detail =
new Detail()
{
Address =
"廣東" ,
Age = 20,
}
};
mongoCollection.Save(userInfo3);
UserInfo userInfo4 =
new UserInfo()
{
UserId =
"1004" ,
UserName =
"趙六" ,
PassWord =
"123456" ,
Detail =
new Detail()
{
Address =
"湖北" }
};
mongoCollection.Save(userInfo4);
} |
4. 定義一個查找數據的方法“Select”,它將查找用戶詳細信息中,地址在湖北的全部用戶:
1
2
3
4
5
6
7
|
/// <summary>
/// 查詢詳細資料地址爲湖北的用戶信息
/// </summary>
public
List<UserInfo> Select() { return
mongoCollection.Linq().Where(x => x.Detail.Address ==
"湖北" ).ToList();
} |
5. 還定義一個刪除數據的方法,將刪除集合全部數據:
1
2
3
4
5
6
7
|
/// <summary>
/// 刪除全部用戶信息
/// </summary>
public
void DeleteAll() { mongoCollection.Remove(x =>
true );
} |
6. 在Main方法中添加如下代碼:
1
2
3
4
5
6
7
8
9
10
11
12
|
static
void Main( string [] args)
{ UserBLL userBll =
new UserBLL();
userBll.InsertSomeData();
var users = userBll.Select();
foreach
(var user in
users) {
Console.WriteLine(user.UserName +
"是湖北人" );
};
userBll.DeleteAll();
} |
7. 最後執行程序,打印如下信息:
李四是湖北人 趙六是湖北人 |
1) 普通實現
普通方式實現不想多講,直接貼代碼,看看與linq方式有什麼區別:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
class
Program { static
void Main( string [] args)
{
UserBLL userBll =
new UserBLL();
userBll.InsertSomeData();
var users = userBll.Select();
foreach
(var user in
users) {
Console.WriteLine(user[ "UserName" ].ToString() +
"是湖北人" );
};
userBll.DeleteAll();
Console.ReadLine();
}
} public
class UserBLL
{ public
string databaseName =
"myDatabase" ;
public
string collectionName =
"UserInfo" ;
private
Mongo mongo; private
MongoDatabase mongoDatabase; private
MongoCollection<Document> mongoCollection; public
UserBLL() {
mongo =
new Mongo(connectionString);
mongoDatabase = mongo.GetDatabase(databaseName)
as MongoDatabase;
mongoCollection = mongoDatabase.GetCollection<Document>(collectionName)
as MongoCollection<Document>;
mongo.Connect();
}
~UserBLL()
{
mongo.Disconnect();
}
/// <summary>
/// 插入一些數據
/// </summary>
public
void InsertSomeData()
{
Document userInfo1 =
new Document();
userInfo1[ "UserId" ] =
"1001" ;
userInfo1[ "UserName" ] =
"張三" ;
userInfo1[ "PassWord" ] =
"123456" ;
mongoCollection.Save(userInfo1);
Document userInfo2 =
new Document();
userInfo2[ "UserId" ] =
"1002" ;
userInfo2[ "UserName" ] =
"李四" ;
userInfo2[ "PassWord" ] =
"123456" ;
//子文檔
var userInfo2Detail =
new Document();
userInfo2Detail[ "Address" ] =
"湖北" ;
userInfo2Detail[ "Age" ] = 20;
userInfo2[ "Detail" ] = userInfo2Detail;
mongoCollection.Save(userInfo2);
Document userInfo3 =
new Document();
userInfo3[ "UserId" ] =
"1003" ;
userInfo3[ "UserName" ] =
"王五" ;
userInfo3[ "PassWord" ] =
"123456" ;
var userInfo3Detail =
new Document();
userInfo3Detail[ "Address" ] =
"廣東" ;
userInfo3Detail[ "Age" ] = 20;
userInfo3[ "Detail" ] = userInfo3Detail;
mongoCollection.Save(userInfo3);
Document userInfo4 =
new Document();
userInfo4[ "UserId" ] =
"1004" ;
userInfo4[ "UserName" ] =
"趙六" ;
userInfo4[ "PassWord" ] =
"123456" ;
var userInfo4Detail =
new Document();
userInfo4Detail[ "Address" ] =
"湖北" ;
userInfo4[ "Detail" ] = userInfo4Detail;
mongoCollection.Save(userInfo4);
}
/// <summary>
/// 查詢詳細資料地址爲湖北的用戶信息
/// </summary>
public
IEnumerable<Document> Select() {
return
mongoCollection.Find( new
Document { { "Detail.Address" ,
"湖北" } }).Documents;
}
/// <summary>
/// 刪除全部用戶信息
/// </summary>
public
void DeleteAll()
{
mongoCollection.Remove( new
Document { }); }
} |
最後,我們通過這段代碼輸出全部用戶資料信息的BJSON格式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/// <summary>
/// 打印數據BJSON
/// </summary>
public
void PrintBJSON() { string
BJSON = string .Empty;
foreach
(var documet in
mongoCollection.FindAll().Documents) {
BJSON += documet.ToString();
}
Console.WriteLine(BJSON);
} |
結果如下:
1
2
3
4
|
{ "UserId" :
"1001" ,
"UserName" :
"張三" ,
"PassWord" :
"123456" ,
"_id" :
"4d80ec1ab8a4731338000001"
} { "UserId" :
"1002" ,
"UserName" :
"李四" ,
"PassWord" :
"123456" ,
"Detail" : {
"Address" :
"湖北" ,
"Age" : 20,
"Email" :
"[email protected]"
}, "_id" :
"4d80ec1ab8a4731338000002"
} { "UserId" :
"1003" ,
"UserName" :
"王五" ,
"PassWord" :
"123456" ,
"Detail" : {
"Address" :
"廣東" ,
"Age" : 20,
"Email" :
"[email protected]"
}, "_id" :
"4d80ec1ab8a4731338000003"
} { "UserId" :
"1004" ,
"UserName" :
"趙六" ,
"PassWord" :
"123456" ,
"Detail" : {
"Address" :
"湖北"
}, "_id" :
"4d80ec1ab8a4731338000004"
} |
二、包含“子集合”的集合操作
同樣舉個例子:有一個學校人事管理系統要統計班級和學生的信息,現在定義了一個“班級集合”,這個集合裏面的學生字段是一個“學生集合”,包含了本班全部學生。
1) linq方式實現
基礎配置我就不多說了,數據類定義如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/// <summary>
/// 班級信息
/// </summary>
public
class ClassInfo { public
string ClassName {
get ;
set ; } public
List<Student> Students { get ;
set ; }
} /// <summary>
/// 學生信息
/// </summary>
public
class Student
{ public
string Name {
get ; set ; }
public
int Age { get ;
set ; }
} |
查詢叫“張三”的學生在哪個班級,以及他的詳細信息:
(這裏其實是ToList後在內存中查的,linq方式直接查詢好像驅動不支持。)
1
2
3
4
|
public
List<ClassInfo> Select() { return
mongoCollection.Linq().ToList().Where(x => x.Students.Exists(s => s.Name ==
"張三" )).ToList();
} |
1) 普通實現
查詢叫“張三”的學生在哪個班級,以及他的詳細信息:
1
2
3
4
5
|
public
List<Document> Select() { var mongocollection = mongoDatabase.GetCollection( "ClassInfo" );
return
mongocollection.Find( new
Document { { "Students.Name" ,
"張三" } }).Documents.ToList();
} |
打印數據的BJSON:
1
2
3
|
{ "_id" :
"4d814bae5c5f000000005f63" ,
"ClassName" :
"1001" ,
"Students" : [ {
"Name" :
"張三" ,
"Age" : 10 }, {
"Name" :
"李四" ,
"Age" : 0 } ] }
{ "_id" :
"4d814bae5c5f000000005f64" ,
"ClassName" :
"1002" ,
"Students" : [ ] }
{ "_id" :
"4d814bae5c5f000000005f65" ,
"ClassName" :
"1003" ,
"Students" : [ {
"Name" :
"王五" ,
"Age" : 11 }, {
"Name" :
"趙六" ,
"Age" : 9 } ] } |
三、小結
通過本節例子我們發現,MongoDB有它獨特的文檔結構可以描述數據對象之間的一些關係特徵。它雖然沒有關係型數據庫多表符合查詢那樣強大的表間查詢方式,但也可以通過文檔結構描述更靈活的關係特性,可以這麼說,關係型數據庫能做的,MongoDB基本上也可以做到。甚至有些關係數據庫不容易做到的,MongoDB也可以輕鬆做到,比如,描述數據類的繼承關係等。
出處:[Lipan] (http://www.cnblogs.com/lipan/)
版權聲明:本文的版權歸作者與博客園共有。轉載時須註明本文的詳細鏈接,否則作者將保留追究其法律責任。