mongodb индексирует встроенные поля (точечная запись) - PullRequest
7 голосов
/ 22 февраля 2012

Давайте предположим, что это документ, представляющий клиента.

{
    company_name: 'corporate ltd.',
    pocs: [
       {name: 'Paul', email: 'paul@corporate.com'},
       {name: 'Jessica', email: 'jessica@corporate.com'}
    ]
}

Я хотел определить уникальный индекс для pocs.email Поэтому я ввел следующую команду:

db.things.ensureIndex({"pocs.email": 1}, {unique: true})

Странно то, что при попытке добавить другую компанию с документом, имеющим адрес электронной почты, уже существует в другой компании, Монго отклоняет это, соблюдая ограничение уникального индекса.

, то есть следующее не может существовать:

{
    company_name: 'corporate ltd.',
    pocs: [
       {name: 'Paul', email: 'paul@corporate.com'},
       {name: 'Jessica', email: 'jessica@corporate.com'}
    ]
},
{
    company_name: 'contoso llc',
    pocs: [
       {name: 'Paul', email: 'paul@corporate.com'},
    ]
}

Что хорошо.Однако возможно наличие дублирующего документа в одном документе, например,

{
    company_name: 'corporate ltd.',
    pocs: [
       {name: 'Paul', email: 'paul@corporate.com'},
       {name: 'Paul', email: 'paul@corporate.com'},
       {name: 'Jessica', email: 'jessica@corporate.com'}
    ]
},

см. Последовательность моих команд cli ниже:

> version()
version: 2.0.2
>
> use test
switched to db test
> db.test.ensureIndex({"poc.email": 1}, {unique: true})
> 
> db.test.insert({company: "contoso", poc: [{email: 'me@comapny.com'}]})
> db.test.insert({company: "contoso", poc: [{email: 'me@comapny.com'}]})
E11000 duplicate key error index: test.test.$poc.email_1  dup key: { : "me@comapny.com" }
> ({company: "contoso", poc: [{email: 'me.too@comapny.com'}, {email: 'me.too@company.com'}]})
> 
> 
> db.test.find()
{ "_id" : ObjectId("4f44949685926af0ecf9295d"), "company" : "contoso", "poc" : [ { "email" : "me@comapny.com" } ] }
{ "_id" : ObjectId("4f4494b885926af0ecf9295f"), "company" : "contoso", "poc" : [ { "email" : "me.too@comapny.com" }, { "email" : "me.too@company.com" } ] }

Более того, это происходит либо в insert, либо в update.

> db.test.update({"_id" : ObjectId("4f44949685926af0ecf9295d")}, {$push: { poc: {email: 'me@company.com'}}})
> db.test.find()
{ "_id" : ObjectId("4f4494b885926af0ecf9295f"), "company" : "contoso", "poc" : [ { "email" : "me.too@comapny.com" }, { "email" : "me.too@company.com" } ] }
{ "_id" : ObjectId("4f44949685926af0ecf9295d"), "company" : "contoso", "poc" : [        {       "email" : "me@comapny.com" },   {       "email" : "me@company.com" },   {       "email" : "me@company.com" } ] }
> 

Это ошибка или by-design-feature Я пропустил поиск в документации?

1 Ответ

8 голосов
/ 22 февраля 2012

Существует открытая проблема, связанная с той же проблемой уникальные индексы, которые не применяются в массиве одного документа .Вы можете проголосовать за него.

Также в этом аналогичном посте Кайл Банкер предлагает хороший обходной путь Уникальные индексы для встроенных документов

Обновление

Это относится не только к встроенным полям, мы можем воспроизвести то же самое для полей массива.

>db.uniqqueTest.insert({a:[1],x:1})
>db.uniqqueTest.createIndex({a:1}, {unique: true})
> db.uniqqueTest.find()
{ "_id" : ObjectId("4f44c6252434860b44986b02"), "a" : [ 1 ],"x":1 }

и выдает ошибку, если мы пытаемся создать новый документ сто же значение (правильное поведение)

> db.uniqqueTest.insert({a:[1],x:3})
E11000 duplicate key error index: stack.uniqqueTest.$a_1  dup key: { : 1.0 }

Но это работает нормально, если мы поместим одно и то же значение в массив (без ошибок, молча принимает дублирующее значение внутри массива)

> db.uniqqueTest.insert({a:[2],x:2})
> db.uniqqueTest.update({x:2},{$push:{a:2}})
{ "_id" : ObjectId("4f44c65f2434860b44986b05"), "a" : [ 2, 2 ], "x" : 2 }

Но не для этого

> db.uniqqueTest.update({x:2},{$push:{a:1}])
E11000 duplicate key error index: stack.uniqqueTest.$a_1  dup key: { : 1.0 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...