为了账号安全,请及时绑定邮箱和手机立即绑定

mongodb如何对含有内嵌数组的集合进行检索

/ 猿问

mongodb如何对含有内嵌数组的集合进行检索

缥缈止盈 2019-05-14 09:08:52

mongodb如何对含有内嵌数组的集合进行检索


查看完整描述

2 回答

?
叮当猫咪

我用的是mongoose,不过也可以直接写mongodb的查询

var GoodSchema = new Schema({ name: String});

var ShopSchema = new Schema({
userId: Schema.ObjectId,
name: String,
point: {type: [Number], index: '2d'},
goods: [GoodSchema],
tags: {},
categorys: [String]
});

现在我想要根据给定的point 和商品名称,查找某个点附近的店家里面谁有卖这里商品的
原先查询语句是写成
var userPoint = [118.4444, 24.4444]
var content = "耳机"
var regexp = new Regexp(content);
ShopModel.find({point: {$near: userPoint}, goods: {$elemMatch: {name: regexp}}}).limit(100).exec(cb)

然后发现返回过来的商店里面带有的商品信息(goods)是所有的商品信息,不是我想要的只有匹配的商品的信息(mongodb 默认返回整个文档,除非你提供了projection)

接着去看了下mongodb的官方文档的projection里面的$,$elemMatch
但是根据官方文档里面讲的,无论$,还是$elemMatch都是返回数组里面第一个匹配元素,并不能像我所需要的返回所有匹配的元素

然后还大概了解了下 map/reduce, 但是不知道是不是该用它,还是有其他什么解决方案
(主要是性能考虑,如果采用map/reduce 显然对数组里面的每个元素都进行了一次过滤,然后如果说商家数量多点,商品数量多点,会不会死的比较惨。。。)

================
还是说我这个数据结构设计不合理,把商品单独出来
var GoodSchema = new Schema({ name: String, shopPoint: {type: [Number], index: '2d'}, shopId: Schema.ObjectId});

var ShopSchema = new Schema({
userId: Schema.ObjectId,
name: String,
point: {type: [Number], index: '2d'},
tags: {},
categorys: [String]
});





查看完整回答
反对 回复 2019-05-15
?
慕瓜9086354

有一个user类,他包含一个标签属性,这个标签是一个数组,数组里面的元素是内嵌文档,格式如下:
<!-- lang: js -->
{
"_id" : "195861",
"tags" : [
{
"tagId" : NumberLong(766),
"optDate" : ISODate("2013-08-12T15:21:02.930Z"),
"enable" : true
},
{
"tagId" : NumberLong(778),
"optDate" : ISODate("2013-08-12T15:21:02.930Z"),
"enable" : true
}
]
}
下面对这个文档中的tag进行增删该查操作,这里用到了spring mongodb 里面的MongoTemplate类。我这里把tags里的内嵌文档抽象成了Tag类。代码删除和修改本身就包含查询方法,所以没写查询方法
代码如下:
<!-- lang: java -->
/**
*
* @author zhangdonghao
*
*/
@Component("UserrTagServiceImpl")
public class UserrTagServiceImpl implements UserrTagService {
/**
* Mongo DB Spring Template
*/
@Resource
protected MongoTemplate mongoTemplate = null;
public UserrTagServiceImpl() {
}
/**
**给tags数组添加一个元素
*/
@Override
public Response<Integer> addTag(String id, Long tagId) {
try {
Tag tag = new Tag(tagId);
tag.setOptDate(new Date());
tag.setEnable(true);
Query query = Query.query(Criteria.where("_id").is(id));
Update update = new Update();
update.addToSet("tags", tag);
mongoTemplate.upsert(query, update, User.class);
} catch (Exception e) {
return new Response<Integer>(0);
}
return new Response<Integer>(1);
}
/**
**修改tags数组中内嵌文档指定一个元素的值
*/
@Override
public Response<Integer> disableTag(String id, Long tagId) {
try {
Query query = Query.query(Criteria.where("_id").is(id)
.and("tags.tagId").is(tagId));
Update update = new Update();
update.set("tags.$.enable", false);
mongoTemplate.updateFirst(query, update, User.class);
} catch (Exception e) {
return new Response<Integer>(0);
}
return new Response<Integer>(1);
}
/**
**删除tags数组中指定的内嵌文档
*/
@Override
public Response<Integer> removeTag(String id, Long tagId) {
try {
Query query = Query.query(Criteria.where("_id").is(id)
.and("tags.tagId").is(tagId));
Update update = new Update();
update.unset("tags.$");
mongoTemplate.updateFirst(query, update, User.class);
} catch (Exception e) {
return new Response<Integer>(0);
}
return new Response<Integer>(1);
}
public MongoTemplate getMongoTemplate() {
return mongoTemplate;
}
public void setMongoTemplate(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
}





查看完整回答
反对 回复 2019-05-15

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信