Mongodb: читать документы / массивы и немедленно удалять их

0

Техническая информация. Я использую tokumx (блокировка уровня документа поддержки) и php.

Структура документа похожа на

{
  "accounts": [
    {
      "username": "1",
    },
    {
      "username": "2",
    }
  ],
  "site": "test.com"
}

Ситуация:

В большинстве случаев мне нужны только первые учетные записи x из массива "учетные записи".

В считанные минуты эти первые учетные записи x будут удалены из массива "учетные записи" в документе.

Компромисс, который я могу сделать:

извлеките "учетные записи".

  {
    "username" : "1",
    "site": "test.com"
  },

  {
    "username" : "2",
    "site": "test.com"
  }

Или переключитесь на MySql (последний параметр).


Теги:
mongodb-query

2 ответа

2
Лучший ответ

Это был почти комментарий, но это длинный комментарий с большим количеством объяснений и примеров. Лично не то, что знакомо с tokumx (как в, я просто никогда не использовал его), но у MongoDB есть способ сделать это, а это . findAndModify().

В основном вы "обновляете" документ или "удаляете" в этом случае, но у вас есть возможность увидеть либо "предварительно измененную", либо "пост-измененную" форму в возвращаемом результате.

Поэтому для работы с массивом вы вызываете так:

 $doc = $collection->findAndModify(
     array(),                                       # Something representing the "query"
     array( 
         '$pull' => array(                          # Basicallly the update
             'accounts' => array( 'username' => 1 ) 
         )
     ),
     null,                                          # optional projected fields
     array(                                         # this is the "options"
         "new" => FALSE,                            # which is the default
     )
 );

И для простого документа:

 $doc = $collection->findAndModify(
     array( 'username' => 1 ),             
     array(),                                       # update, doesn't matter
     null,
     array( "remove" => TRUE )
 );    

Отмечая ваш комментарий, вы удаляете первые n элементов массива с $push оператора $push довольно забавно. Существует модификатор $slice, который делает это:

 $doc = $collection->findAndModify(
     array(),                                       # Something representing the "query"
     array( 
         '$push' => array(                          # Basicallly the update
             'accounts' => array(
                 '$each' => array(),                # But blank
                 '$slice' => lengthOfArrayMinusNElements                
             )
         )
     ),
     null,                                          # optional projected fields
     array(                                         # this is the "options"
         "new" => FALSE,                            # which is the default
     )
 );

Не "супер" атом, так как вам нужно знать, "сколько времени" массив, но это можно сделать. Кажется странным, я знаю, но вы в основном добавляете "ничего" в массив, но ограничиваете его длиной и удаляете элементы через $slice. Две формы, одна для проекции, другая - модификатор обновления, как показано.

  • 0
    спасибо за размещение примера php. Надеюсь, вы не возражаете против другого вопроса, не могли бы вы показать мне, как использовать массив «учетные записи» массива $ slice x в findAndModify, если это возможно.
  • 0
    Я думаю, это третьи аргументы. array( 'accounts' => array('$slice' => 5)) спасибо!
Показать ещё 6 комментариев
2

Не совсем уверен в структуре, чего вы хотите достичь, но операция, которую вы хотите для первой части, - findAndModify(). Так что удар в темноте (mogoshell, так как я не знаю драйвера php)

db.accounts.findAndModify({query: {"site": "test.com", "accounts.username":"2"},
                           update : {$pull: {"accounts" :{ "username" : "2"}})

Чтобы получить только первые хэлементы массива, вы можете использовать оператор $ slice в проекционной части вашего запроса, например,

db.accounts.find({},{ accounts : { $slice: 5 }})

или в findAndModify добавьте

fields: { accounts : { $slice: 5 }}
  • 0
    Благодарю. Я попробую. Нет способа извлечь первые n элементов из массива "account", верно?
  • 0
    добавил это к ответу
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню