我有一个如下文档,我想用给定的MAC和给定的fingerId更新一个AccessPoint的字段,例如RSSI。目前,我正在通过以下方法实现此目的:首先找到accessPoint的索引,然后更新其字段。有什么更好的方法吗?
这是示例文档
"_id" : ObjectId("5d00d45bef388e16b9406b13"),
"x" : 7.2,
"y" : 4.5,
"visitTime" : NumberLong(1560337948058),
"gridNumber" : NumberInt(-1),
"fingerprints" : [
{
"accessPoints" : [
{
"MAC" : "MAC5",
"SSID" : "SSID3",
"RSSI" : NumberInt(20)
},
{
"MAC" : "MAC6",
"RSSI" : NumberInt(20)
}
],
"orientation" : NumberInt(0),
"fingerId" : NumberInt(0)
}
],
这就是我目前正在做的事情:
Query query = new Query(new Criteria().andOperator(
Criteria.where(Fields._ID).is(new BsonObjectId(new ObjectId(obsId))),
Criteria.where("fingerprints").elemMatch(Criteria.where("fingerId").is(fingerDoc.getId())),
Criteria.where("fingerprints.accessPoints").elemMatch(Criteria.where("MAC").is(mac))
));
int index = getIndexOfAP(collection,obsId, mac);
if(index != -1) {
Update update = new Update().set("fingerprints.$.accessPoints." + index + ".RSSI", newValue.getRSSI());
UpdateResult updateResult = mongoTemplate.updateMulti(query, update, collection);
}
我也尝试使用fingerprints.$.accessPoints.$.RSSI
,并且得到too many $ error
可以使用除重新设计数据库以外的使用多个$的任何替代解决方案。
答案 0 :(得分:0)
这是我考虑到MAC在我的情况下是唯一的事实的解决方案:
BsonDocument bsonDocument = new BsonDocument();
bsonDocument.append(Fields._ID,new BsonObjectId(new ObjectId(obsId)));
bsonDocument.append("fingerprints.fingerId",new BsonInt32(fingerprintDoc.getFingerId()));
mongoTemplate.getCollection(collection).updateMany(bsonDocument,
new Document().append("$set", new Document().append("fingerprints.$.accessPoints.$[item].RSSI", newValue.getRSSI())),
new UpdateOptions()
.arrayFilters(
Collections.singletonList( Filters.in("item.MAC",
Collections.singletonList(mac)) ))
);
以这种方式,我首先用给定的ID查找所需的指纹,并更新与mac匹配的accessPoint的RSSI,这就是我要寻找的