我正在使用MongoDB $addToSet
,如下所示:
.AddToSet(report => report.EngineReports, engineReport);
EngineReport
是类,而不是MongoDB文档中的字符串或整数,它是类FileAggregationReport
中的一部分:
public class FileAggregateReport
{
public Guid FileId { get; set; }
public Guid CorrelationId { get; set; }
public List<EngineReport> EngineReports { get; set; }
}
现在我的问题是我有重复项,因为如果我有2个具有相同ID但其他属性不同的对象,则会将这2个类添加到集合中。
示例:
头等舱
new EngineReport()
{
EngineType = EngineType.TypeA,
Summary = "test1"
}
第二堂课
new EngineReport()
{
EngineType = EngineType.TypeA,
Summary = "test2"
}
因此,当我使用addToSet将其添加到EngineReports时,我的问题是2个类,但我只想添加一个,是否可以?
如何在addToset之前检查此类是否与集合中的ID相同?
答案 0 :(得分:1)
来自$addToSet文档:
如果值为文档,则如果数组中的现有文档与要添加的文档完全完全匹配,则MongoDB会确定该文档为重复文档;即现有文档具有完全相同的相同字段和值,且这些字段的顺序相同。
因此,这对您的情况没有帮助。
您可以采用其他方法,并在更新操作中更改过滤器部分。例如,假设当前您通过FileId
字段进行匹配。您可以添加其他检查,以确保更新的文档中没有EngineType.TypeA
。这将对您尝试插入的第一个EngineReport
有效,但对于第二个var filterBuilder = Builders<FileAggregateReport>.Filter;
var regularFilter = filterBuilder.Eq(x => x.FileId, fileId);
var engineType = Builders<EngineReport>.Filter.Eq(x => x.EngineType, EngineType.TypeA);
var engineTypeFilter = filterBuilder.ElemMatch(f => f.EngineReports, engineType);
var combinedFilter = filterBuilder.And(regularFilter, filterBuilder.Not(engineTypeFilter));
var updateBuilder = Builders<FileAggregateReport>.Update;
var update1 = updateBuilder.Push(x => x.EngineReports, engineReport1);
var update2 = updateBuilder.Push(x => x.EngineReports, engineReport2);
myCollection.UpdateOne(combinedFilter, update1); // 1 document affected
myCollection.UpdateOne(combinedFilter, update2); // 0 documents affected
,则不会更新任何文档:
/// Updates The Contents Of Each Node Added To Our NodesAdded Array
///
/// - Parameters:
/// - nodes: [SCNNode]
/// - pointOfView: SCNNode
func updateScaleFromCameraForNodes(_ nodes: [SCNNode], fromPointOfView pointOfView: SCNNode){
nodes.forEach { (node) in
//1. Get The Current Position Of The Node
let positionOfNode = SCNVector3ToGLKVector3(node.worldPosition)
//2. Get The Current Position Of The Camera
let positionOfCamera = SCNVector3ToGLKVector3(pointOfView.worldPosition)
//3. Calculate The Distance From The Node To The Camera
let distanceBetweenNodeAndCamera = GLKVector3Distance(positionOfNode, positionOfCamera)
//4. Animate Their Scaling & Set Their Scale Based On Their Distance From The Camera
SCNTransaction.begin()
SCNTransaction.animationDuration = 0.5
switch distanceBetweenNodeAndCamera {
case 0 ... 0.5:
node.simdScale = simd_float3(0.25, 0.25, 0.25)
case 0.5 ... 1:
node.simdScale = simd_float3(0.5, 0.5, 0.5)
case 1 ... 1.5:
node.simdScale = simd_float3(1, 1, 1)
case 1.5 ... 2:
node.simdScale = simd_float3(1.5, 1.5, 1.5)
case 2 ... 2.5:
node.simdScale = simd_float3(2, 2, 2)
case 2.5 ... 3:
node.simdScale = simd_float3(2.5, 2.5, 2.5)
default:
print("Default")
}
SCNTransaction.commit()
}
}