mongodb 内嵌索引问题

项目中出现了这样一个问题,内嵌唯一索引不生效导致出现不合预期的数据。

找下原因。

document如下:

@Data
@Document(collection = "out")
@CompoundIndexes({
        @CompoundIndex(name = "inner_unique", def = "{'inner.key':1}", unique = true)
})
public class OutDocument {
    @Id
    private String id;

    private String code;

    private String name;

    private List<InnerDocument> inner;
}
@Data
@AllArgsConstructor
public class InnerDocument {

    private String key;

    private String value;
}

测试方法:

@Test
    public void saveOrUpdate() {

        OutDocument outDocument = new OutDocument();
        outDocument.setCode("QWER001");
        outDocument.setName("测试索引");

        List<InnerDocument> innerDocuments = Arrays.asList(new InnerDocument("001", "潘森"), new InnerDocument("002", "妖姬"));

        outDocument.setInner(innerDocuments);

        outDocumentRepository.save(outDocument).subscribe(System.out::println);

    }

执行第一遍,看下数据:

{
    "_id": ObjectId("5c2dc8c846ce5e00cc26239c"),
    "code": "QWER001",
    "name": "测试索引",
    "inner": [
        {
            "key": "001",
            "value": "潘森"
        },
        {
            "key": "002",
            "value": "妖姬"
        }
    ],
    "_class": "com.paranoia.webfluxreactive.collection.index.OutDocument"
}

再次执行这个插入方法:

Caused by: com.mongodb.MongoWriteException: E11000 duplicate key error collection: test.out index: inner_unique dup key: { : "001" }

索引生效。

到这里我们没有发现什么问题,姿势正确。

那么,换一个姿势,修改inner。

@Test
    public void addToInnerIndex() {

        Mono<OutDocument> documentMono = outDocumentRepository.findById("5c2dc8c846ce5e00cc26239c")
                .map(result -> {
                    List<InnerDocument> inner = result.getInner();
                    inner.add(new InnerDocument("001", "潘森的爸爸"));
                    return result;
                })
                .flatMap(newOut -> outDocumentRepository.save(newOut));

        documentMono.block();
    }

看下数据:

{
    "_id": ObjectId("5c2dc8c846ce5e00cc26239c"),
    "code": "QWER001",
    "name": "测试索引",
    "inner": [
        {
            "key": "001",
            "value": "潘森"
        },
        {
            "key": "002",
            "value": "妖姬"
        },
        {
            "key": "001",
            "value": "潘森的爸爸"
        }
    ],
    "_class": "com.paranoia.webfluxreactive.collection.index.OutDocument"

发现索引并没有生效,这说明这个姿势不对,不用jpa ,试一下template

@Test
    public void addToInnerIndexTryTemplate() {

        Query query = new Query(Criteria.where("code").is("QWER001"));
        Update update = new Update();
        update.addToSet("inner", new InnerDocument("001", "潘森的爷爷"));

        reactiveMongoTemplate.updateMulti(query, update, OutDocument.class).block();
    }

看下数据,

{
    "_id": ObjectId("5c2dc8c846ce5e00cc26239c"),
    "code": "QWER001",
    "name": "测试索引",
    "inner": [
        {
            "key": "001",
            "value": "潘森"
        },
        {
            "key": "002",
            "value": "妖姬"
        },
        {
            "key": "001",
            "value": "潘森的爸爸"
        },
        {
            "key": "001",
            "value": "潘森的爷爷"
        }
    ],
    "_class": "com.paranoia.webfluxreactive.collection.index.OutDocument"
}

发现还是没有生效,看来这两种姿势都不会在修改内嵌数据的时候去适配索引。那么,这种情况到底该采用一个什么姿势?

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高级摸鱼工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值