寫在前面的話
- 本篇博客主要講 Collection,由於該部分比較長,會用兩到三篇博客的內容描述.其實這個部分東西不好寫博客,因爲涉及到的都是一些操作語句,這個和mongodb的api有關
- 使用的meteor版本爲0.8.0
- 老話重提 ,儘量以官方文檔爲主
- 本篇博客有不正確的地方在所難免,如有發現望指出。
- 本篇博客地址:http://blog.csdn.net/a6383277/article/details/23656929 轉載請註明出處,謝謝
- 編程環境:ubuntu (涉及到的shell,代碼等)
Collections
Collctions是meteor中的比較重要的部分,Meteor把數據存儲到Collection中。 Collections對象的函數主要是對數據集合的CURD等操作。如何你對NoSQL有一定的瞭解的話,那麼對這個對象應該會比較熟悉,它的操作與 NoSQL語句類似。 在Meteor中,現在主要是使用Mongodb,在官方文檔中,開發者表示會支持其他的數據庫,不過那是在將來了。
構造函數 new Meteor.Collection(name, [options]) @Anywhere
如果你要聲明一個數據集合Collection(類似於sql中的表的概念),那麼就用上面的構造函數了。先看下它的參數:
name
數據集的名字,String類型。在Mongodb中就有一個與之對應的Collection了。如果這個name爲null,那麼只是生成一個非託管的(臨時的數據集合)數據集合了。至於是什麼意思的,下文通過代碼來解釋。
options
可選的參數有:
connection.這是個object對象,指定連接的服務器對象.具體可以見上一篇博客DDP subscribe相關的內容.這個時候就是訂閱遠程的數據集了.
如果name爲空,那麼就不能使用這個選項.默認情況都是省略該選項的,表明連接本地數據.
idGeneration: 每條數據_id生成的方案,字符串.有兩個選擇:'STRING'和'MONGO',STRING是一個隨機字符串.而MONGO是一個Mongodb的ObjectID對象.使用過就清楚了.默認是 STRING.
transform:在數據發送之前進行一定的處理.它是個function
因此可以像下面幾種方式使用:
//1.創建一個本地數據集,不會保存到數據庫.也不會進行前後臺同步,更不會多客戶端同步了..
LocalPeople = new Meteor.Collection(null);
//2創建一個數據集,會保存到數據庫.這是最普通的用法.也是最普遍的用法
People = new Meteor.Collection("people")
//3.創建一個遠程服務器的數據集引用.它不會保存到本地數據庫
var remote = DDP.connect('http://localhost:3010');
RemotePeople = new Meteor.Collection("people",remote)
//4.創建一個數據集指定它的ID生成方式
IDPeople = new Meteor.Collection("idpeople",{'idGeneration':'MONGO'})
//或者
//IDPeople = new Meteor.Collection('idpeople',remote,'MONGO')
//5.使用transform
TransformPeople = new Meteor.Collection('tranpeople',{'transform':function(docs){
console.log("transform:")
docs['transform']=true;
console.log(docs);
return docs;
}});
具體區別請看源碼中的defineCollection函數輸出。
collection.find(selector, [options])
這個是數據查詢函數。
selector
selector一個查詢條件。
當它是一個字符串時,
collection.find("string")
等同
collection.find({_id:"string"})
也就是說,如果傳入的是字符串,那麼將被當作數據的_id字段使用。
當它是一個Object對象時,(當爲{}空對象時,查詢所有數據)具體規則可以參考Mongodb的find。這裏不多講,也講不完。具體見http://docs.mongodb.org/manual/tutorial/query-documents/ 和操作符 http://docs.mongodb.org/manual/reference/operator/query/
注意,這個find函數返回的不是一個數據數組,而是一個指向數據集的cursor。具體見下面的Cursor部分。
options
object 。可選的操作。對數據結果的處理選項。
sort:進行數據排序
排序規則
People.find({},{sort:[["age", "asc"], ["name", "desc"]]}) //進行age的升序排列,name的降序排列
或者
People.find({},{sort:{a: 1, b: -1}})
如果什麼都不規定則默認爲 自然語序 如 1,2,3 或者a,b,c,等
skip :number 從開始 跳過多少條數據 返回
limit:number 限制多少條數據返回。
通過使用skip和limit可以實現數據分頁
fields: 返回數據字段限制。
People.find({}, {fields: {age: 0,name:0}}) 返回數據中不包含age,name字段
People.find({}, {fields: {firstname: 1}})返回數據中'只'包含firstname字段
注意0表示 排除,1表示 包含。 這兩者不能同時使用。
這樣使用是錯誤 的:
People.find({}, {fields: {firstname: 1,age: 0}})
但是有一個例外,那就是_id字段。對於_id字段可以同時使用1或0.因爲就算沒有使用_id:1,_id字段也是默認返回的。如果不想要_id可以使用如下:
People.find({}, {fields: {firstname: 1,_id: 0}})
reactive:boolean 設置返回的數據是不是活性數據源。默認值是true
People.find({}, {reactive:false})
如果是活性數據源,那麼引用它的Template和Template對象 一旦結果集發生改變也會跟着改變。
非活性數據源則不會帶來Template的影響。具體請見Session博客那一章。
transform:重寫(如果在new Meteor.Collection('xxx',{transform:function(doc){..}})定義過的話)或者新增對於返回前 數據的修改等操作。
在當前代碼裏面,不展示關於remote的使用,我會註釋掉相關,代碼,如果你想使用,請把上篇博客的DDP的main-server跑在3010端口,在取消代碼裏面的註釋即可。在下載代碼包裏,我會包含這個兩個。shell是:
cd main-server
meteor run -p 3010
新開一個終端
cd deputy-server
meteor
deputy-server 結構如下:
- 根目錄
|-Collection.js
-- client 文件夾
|-client.js
|-index.html
-- server 文件夾
|-main.js
Collection.js
//var remote = DDP.connect("http://localhost:3010");//鏈接遠程服務器
//People = new Meteor.Collection('people',remote)
//創建一個本地(臨時)數據集,不會保存到數據庫.
LocalPeople = new Meteor.Collection(null);
//創建一個數據集,會保存到數據庫.這是最普通的用法.也是最普遍的用法
People = new Meteor.Collection("people")
//創建一個遠程服務器的數據集引用.它不會保存到本地數據庫
//var remote = DDP.connect('http://localhost:3010');
//RemotePeople = new Meteor.Collection("people",remote)
//創建一個數據集指定它的ID生成方式
IDPeople = new Meteor.Collection("idpeople",{'idGeneration':'MONGO'})
//或者
//IDPeople = new Meteor.Collection('idpeople',remote,'MONGO')
//5.使用transform
TransformPeople = new Meteor.Collection('tranpeople',{'transform':function(docs){
//console.log("transform:==============開始")
docs['transform']=true;
//console.log(docs);
//console.log("transform:==============結束")
return docs;
}});
client.js
注意所有的打印都在瀏覽器控制檯
//不同定義的Collection
function defineCollection(){
console.log("================================defineCollection");
console.log("RemotePeople findOne:");
console.log(RemotePeople.findOne());
console.log("IDPeople findOne:");
console.log(IDPeople.findOne());
console.log("People findOne:");
console.log(People.findOne());
console.log("LocalPeople findOne:");
console.log(LocalPeople.findOne());
console.log("================================defineCollection");
}
Meteor.setTimeout(defineCollection,5000);
function show(object){
console.log(JSON.stringify(object))
}
//find函數
function find(){
console.log("原始數據:")
var oriResult = People.find({}).fetch()
show(oriResult);
console.log("sort:");
var sortResult = People.find({},{sort:{age:1}}).fetch(); //結果集以age升序
show(sortResult)
console.log("fields : 只顯示name字段(默認情況下會顯示_id字段)");
var fieldsResult1 = People.find({},{fields:{name:1}}).fetch();
show(fieldsResult1)
console.log("fields : 只顯示name字段,不顯示_id字段");
var fieldsResult2 = People.find({},{fields:{name:1,_id:0}}).fetch();
show(fieldsResult2)
console.log("fields : 隱藏phone字段");
var fieldsResult3 = People.find({},{fields:{phone:0}}).fetch();
show(fieldsResult3)
console.log("skip,limit : 跳過兩條數據,然後顯示2條數據");
var skipResult2 = People.find({},{skip:2,limit:2}).fetch();
show(skipResult2)
console.log("綜合應用 : 以age升序,跳過兩條數據,然後顯示2條數據,隱藏phone字段");
var result = People.find({},{skip:2,limit:2,fields:{phone:0},sort:{age:1}}).fetch();
show(result)
console.log("在上一個結果綜合應用上所有age + 20")
var result2 = People.find({},{skip:2,limit:2,fields:{phone:0},sort:{age:1},transform:function(doc){
doc.age = doc.age+20
return doc;
}}).fetch();
show(result2)
}
Meteor.setTimeout(find,10000);
//活性數據源
Template.relative.people = function(){
return People.find({}).fetch();
}
//非活性數據源
Template.noRelative.people = function(){
return People.find({},{reactive:false}).fetch();
}
function changeDate(){
People.insert({age:1000,name:"ChageDate"})
}
//20秒後 改變數據源 發現 沒有reactive:false的 改變了,有reactive:false的部分沒有改變
//(注意這裏需要刷新一次頁面後才能看到效果,因爲本地的數據還沒有從服務器拿過來就在頁面上顯示了,
//這是頁面是無數據的,然後服務器數據拉取過來後,數據變化了,前一個是活性數據源所以馬上就顯示了,
//後一個非活性數據源,就不會顯示數據,所以需要在頁面要等數據緩存下來後刷新一次後,在插入數據才能看到效果
//其實,第一次數據顯示不出來 也是設置了非活性數據選項的原因)
Meteor.setTimeout(changeDate,15000);
index.html
<body>
relative====================<br>
{{> relative}}
<br>======================================<br>
no relative====================<br>
{{> noRelative}}
</body>
<Template name="relative">
{{#each people}}
{{name}}-{{age}}-{{address}}<br>
{{/each}}
</Template>
<Template name="noRelative">
{{#each people}}
{{name}}-{{age}}-{{address}}<br>
{{/each}}
</Template>
main.js
Meteor.startup(function(){
People.remove({});
//這裏的People使用的就是collections.js中定義的數據集操作對象
var peoples = [
{name:"小A",address:"長沙",phone:"111",age:2},
{name:"小B",address:"常德",phone:"222",age:4},
{name:"小C",address:"衡陽",phone:"333",age:3},
{name:"小D",address:"衡南",phone:"444",age:1},
{name:"小E",address:"株洲",phone:"555",age:10}
];
for (var i = 0; i < peoples.length; i++)
People.insert(peoples[i]);
//LocalPeople初始化一條數據
LocalPeople.insert({name:"LocalPeople"}); //無法在客戶端找到它,因爲它是非同步的
IDPeople.insert({name:"IDPeople"})
TransformPeople.insert({name:"TransformPeople"})
});
第一部分到此結束
代碼下載去我的github:github.com/huyinghuan/Lesson 的Meteor/API-007目錄下。
或者CSDN下載: