说到数据库经典场景就是视图了,视图是一个虚拟表,具有实时更新性,和重新创建一个表,并通过程序控制更新的成本比起来,视图的成本是真的底很多,在mongo中是否有视图呢,答案是肯定的。
视图创建以及删除
这里我们还是使用此前lookup文章的脚本。
db.createView (
"orderDetails",
"orders",
[
{ $lookup: { from: "inventory", localField: "item", foreignField: "sku", as: "inventory_docs" } },
// 下面是投影映射,可以指定设置关联有需要的字段,0是不要,1是要
// { $project: { "inventory_docs._id": 0, "inventory_docs.sku": 0 } }
]
)
执行后,使用navicat15版本可以看见视图已经成功创建。
删除视图
db.orderDetails.drop()
使用脚本操作查询
db.orderDetails.find({'inventory_docs.sku':{'$in':['pecans']}})
使用Java程序进行查询
创建springboot项目配置连接以及给mongodb配置驼峰映射,日志打印
#驼峰映射
spring.data.mongodb.field-naming-strategy=org.springframework.data.mapping.model.SnakeCaseFieldNamingStrategy
#日志打印
logging.level.org.springframework.data.mongodb.core= DEBUG
注意视图对象是只读集合喔,只能进行查询操作!!
Java实体类:
@Document(collection = "inventory")
public class Inventory implements Serializable {
@Id
private Double _id;
private String sku;
private String description;
private Double instock;
//省略gettter,setter
}
@Document(collection = "orders")
public class Orders implements Serializable {
@Id
private Double _id;
private String item;
private Double price;
private Double quantity;
private List<Inventory> inventory_docs;
//省略gettter,setter
}
@Document(collection = "orderDetails")
public class OrderDetails {
@Id
private Double _id;
private String item;
private Double price;
private Double quantity;
private List<Inventory> inventory_docs;
//省略gettter,setter
}
以spring的mongoTemple为例子,编写测试用例
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void testSpringMongoView(){
BasicDBObject query = new BasicDBObject();
query.put("inventory_docs.sku",new BasicDBObject("$in", new String[]{"pecans"}));
MongoCollection<Document> orderDetails = mongoTemplate.getCollection("orderDetails");
FindIterable<Document> documents = orderDetails.find(query);
MongoCursor<Document> iterator = documents.iterator();
System.out.println("方法一");
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("方法二");
Query springMongoQuery = new Query();
Criteria criteria = Criteria.where("inventory_docs.sku").in(new String[]{"pecans"});
springMongoQuery.addCriteria(criteria);
List<OrderDetails> orderDetails1 = mongoTemplate.find(springMongoQuery, OrderDetails.class);
orderDetails1.forEach(System.out::println);
}
运行结果:
值得注意的是有个坑你的集合类属性如果编写的是小驼峰的形式,有时候下划线和小驼峰在lookup后的as不一定映射的上,推荐as的时候带下划线,然后查询条件也使用_下划线的写法,实体类的属性写小驼峰或下划线都可