首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >猫鼬findOneAndUpdate +向上插入总是替换现有的文档

猫鼬findOneAndUpdate +向上插入总是替换现有的文档
EN

Stack Overflow用户
提问于 2021-04-15 20:08:44
回答 1查看 439关注 0票数 0

我有一个集合,我想用findOneAndUpdate重新插入。此外,我还有两个字段(isHandled,isNotADuplicate),它们应该是:

  • 在插入
  • 时默认为'false‘,在更新时未被更改(例如,isHandled保持“真”)

然而,我发现

  • isHandled,isNotADuplicate总是默认为'false'
  • _id也会在每次更新时重新生成(我使用复合键查询文档,而不是_id)

我的模型

代码语言:javascript
复制
export const QuickbrainFindingSchema = new Schema<QuickBrainFindingDocument>({
    
    connectedApplicationType: { type: String, required: true, enum: ['jira'] },//e.g. jira
    clientKey: { type: String, required: true },//e.g. 135eb702-156c-3b67-b9d0-a0c97548xxxx
    
    //key
    projectKey: { type: String, required: true },//e.g. AL
    type: { type: String, required: true },
    doc1key: { type: String, required: true },//e.g. AL-7
    doc2key: { type: String, required: true },//e.g. AL-16
    
    //data
    calculationDate: { type: SchemaTypes.Date, default: Date.now },
    direction: { type: String, required: true },
    reasonAndMetric: { type: SchemaTypes.Mixed, reason: true },
    scoreSummary: { type: String, reason: true },

    isHandled: { type: SchemaTypes.Boolean, default: false },
    isNotADuplicate: { type: SchemaTypes.Boolean, default: false },

    similarityReference: { type: SchemaTypes.ObjectId, required: true, ref: "QuickbrainSimilarityMatrix" }

}, {
    //options
});

QuickbrainFindingSchema.index(
    { connectedApplicationType: 1, clientKey: 1, project: 1, doc1key: 1, doc2key: 1, type: 1 },
    { unique: true, name: "compoundKey" }
);

export const QuickbrainFindingModel = model<QuickBrainFindingDocument>("QuickbrainFinding", QuickbrainFindingSchema);

我的密码

代码语言:javascript
复制
public async addFinding(
        projectKey: string,
        doc1key: string,
        doc2key: string,
        type: ET_FindingType
        , data: QuickbrainFindingData): Promise<QuickbrainFinding> {

        let keyFull: QuickbrainFindingKey = {
            connectedApplicationType: this.connectedApplicationType,
            clientKey: this.clientKey,
            projectKey: projectKey,
            doc1key: doc1key,
            doc2key: doc2key,
            type: type
        };

        let insertObj: QuickbrainFinding = <QuickbrainFinding><unknown>{};
        Object.assign(insert, keyFull);
        Object.assign(insert, data);

        delete (<any>insertObj).isHandled;
        delete (<any>insertObj).isNotADuplicate;

        return new Promise<QuickbrainFinding>(function (ok, nok) {

                QuickbrainFindingModel.findOneAndUpdate(
                    keyFull, { $set: insertObj},
                    {
                        runValidators: true,
                        upsert: true,
                        setDefaultsOnInsert: true,
                        new: true,
                        omitUndefined: true,//I think only available for findAndReplace(..)
                    })
                .lean().exec(function (err, result) {
                    if (err) {
                        nok(err);
                    }
                    else
                        ok(result)
                });

        });

    }

猫鼬调试输出

代码语言:javascript
复制
        quickbrainfindings.findOneAndUpdate(
            {
                connectedApplicationType: 'jira',
                clientKey: '135eb702-256c-3b67-b9d0-a0c975487af3',
                projectKey: 'ITSMTEST',
                doc1key: 'ITSMTEST-7',
                doc2key: 'ITSMTEST-10',
                type: 'Email'
            },
            {
                '$setOnInsert':
                    { __v: 0, isHandled: false, isNotADuplicate: false, _id: ObjectId("60789b02c094eb3ef07d2929") },
                '$set': {
                    connectedApplicationType: 'jira',
                    clientKey: '135eb702-256c-3b67-b9d0-a0c975487af3', projectKey: 'ITSMTEST', doc1key: 'ITSMTEST-7', doc2key: 'ITSMTEST-10', type: 'Email',
                    calculationDate: new Date("Thu, 15 Apr 2021 19:58:58 GMT"),
                    direction: '2', scoreSummary: '100.0%',
                    similarityReference: ObjectId("60789b029df2079dfa8aa15a"),
                    reasonAndMetric: [{ reason: 'Title Substring', metricScore: '100%' },
                    { reason: 'Title TokenSet', metricScore: '54%' }, { reason: 'Description TokenSet', metricScore: '100%' }]
                }
            },
            {
                runValidators: true, upsert: true, remove: false, projection: {},
                returnOriginal: false
            }
        )

会发生什么?

找到了现有的文档,但是当它们被更新时,我感到困惑的是:

  • _id is regenerated
  • isHandledisNotADuplicate被重置为'false‘(尽管insertObj不包含它们),在查看调试输出时,我可以看到,新的_id是fron $setOnInsert,这让我感到困惑,因为选择器工作

值得注意

  • keyFull用于查询现有文档,它不包含_id;
  • delete (<any>insertObj).isHandled <- -用于$set的对象不包含isHandled
EN

回答 1

Stack Overflow用户

发布于 2021-04-16 06:11:40

承认这一点令人尴尬,但多亏了Joe,我发现了这个问题。

在每个findOneAndUpdate / Upsert之前,我都有一个delete语句删除现有的文档管道:

删除旧的documents

  • Calculate新documents

  • Upsert新文档->总是导致插入

代码语言:javascript
复制
            let matchAnyDoc = this.filterForDocKeyAny(projectKey, docKeyAny, findingType);
            matchAnyDoc.forEach(async (condition) => {
                QuickbrainFindingModel.deleteMany(condition).exec(function (err, res) {
                    if (err) {
                        nok(err);
                    } else {
                        ok();
                    }
                });

            }, this);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67115394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档