使用morphia对基于mongodb应用开发
最近初学了下mongoDB,作为比较火的一个NoSQL数据库,确实比较强大,但是这几天学下来更多的感觉到的是学习、使用都很方便。首先是初学者体验使用方便,直接下载(http://www.mongodb.org/downloads)解压,然后启一下服务便可使用:mongod --dbpath your_db_data_dir,启动以后默认端口27017, 默认http端口28017,可以通过http://localhost: 28017 查看基本信息。当然,如果你还没有下载的想法,可以直接在其官网上尝试Try The Online Shell,就可以使用其来做各种操作,当然online的功能较少。
其次,一改关系数据库的表模型,mongodb是一个以松散的集合形势呈现,这种no shema让我感觉非常方便。从开发人员的角度看,mongodb中的每一个数据对象就是一个JSON,所有的操作(save,update,find etc.)都可以像操作JSON一样,当然mongodb数据是一种叫做BSON格式的,即Binary JSON:http://bsonspec.org/ 。例如:
将文档{ name:”abc”,age:12}插入到users集合:
db.users.insert ({name:”abc”,age:12})
修改文档,增加其emails属性:
db.users.update(
{name:"abc"},
{"$set": {emails:["abc@gmail.com","abc@163.com"]}}
)
查找所有users文档:
db.users.find();
查找age > 20的前5个:
db.users.find({
age: {“$gt”:20}
}).limit(5)
删除:db.users.delete({name:”abc”})
这些基本的操作不一一例举,包括像index的操作,统计函数等,总之,一切都是文档:查询表达式是文档、返回数据是文档、修改数据的新值是文档、index的操作也是文档形式等等。另外,诸如其支持的MAPREDUCE操作,只需在其规范内定义自己的map和reduce函数即可完成简单MR计算;使用GridFS规范来存储大文件。
最后的方便之处就是对很多开发语言的支持,PHP, Java, Python, Ruby, Perl。这里我就使用Morphia来做一个非常简单demo: 假设一千个店铺(store)分布在不同的地方(place),每个地方都有一个二维的坐标(x,y)用来表示其位置,我们可以很方便的查找到诸如 离***地方最近的***店铺。整个例子分三步:
1) 准备数据
2) 测试数据是否准备好
3) 查找店铺
使用jars: mongo-2.7.0.jar, morphia-0.98.jar
下面是两个model类:
@Entity(value="stores",noClassnameStored=true)
public class Store {
@Id
private ObjectId id;
private String name;
private String desc;
@Embedded
public Place place;
@Override
public String toString() {
return "Store [desc=" + desc + ", id=" + id + ", name=" +
name + ", place=" + place + "]";
}
public Store(){}
public Store(String name, String desc, Place place) {
this.name = name;
this.desc = desc;
this.place = place;
}
//省略getter,setters
}
@Entity(value="stores",noClassnameStored=true)
public class Store {
@Id
private ObjectId id;
private String name;
private String desc;
@Embedded
public Place place;
@Override
public String toString() {
return "Store [desc=" + desc + ", id=" + id + ", name=" +
name + ", place=" + place + "]";
}
public Store(){}
public Store(String name, String desc, Place place) {
this.name = name;
this.desc = desc;
this.place = place;
}
//省略getter,setters
}
@Embedded
public class Place {
private String name = "";
@Indexed(IndexDirection.GEO2D)
private double[] loc = null;
public Place(String name, double[] loc) {
this.name = name;
this.loc = loc;
}
public Place() {
}
@Override
public String toString() {
return "Place [loc=" + Arrays.toString(loc) + ", name=" + name + "]";
}
//省略getter,setters
}
@Embedded
public class Place {
private String name = "";
@Indexed(IndexDirection.GEO2D)
private double[] loc = null;
public Place(String name, double[] loc) {
this.name = name;
this.loc = loc;
}
public Place() {
}
@Override
public String toString() {
return "Place [loc=" + Arrays.toString(loc) + ", name=" + name + "]";