Условно $ addToSet в mongodb на основе атрибута Objects [duplicate]

Python 3.6.0 Timings

Вот результаты синхронизации с использованием Python 3.6.0. Имейте в виду, что эти времена относятся друг к другу, а не абсолютны.

Я придерживался только мелких копий, а также добавил некоторые новые методы, которые не были возможны в Python2, например list.copy() ( Python3 эквивалент среза ) и распаковки (*new_list, = list):

METHOD                  TIME TAKEN
b = a[:]                6.468942025996512   #Python2 winner
b = a.copy()            6.986593422974693   #Python3 "slice equivalent"
b = []; b.extend(a)     7.309216841997113
b = a[0:len(a)]         10.916740721993847
*b, = a                 11.046738261007704
b = list(a)             11.761539687984623
b = [i for i in a]      24.66165203397395
b = copy.copy(a)        30.853400873980718
b = []
for item in a:
  b.append(item)        48.19176080400939

Мы видим, что старый победитель по-прежнему выходит сверху, но на самом деле не на огромную сумму, учитывая повышенную читаемость подхода Python3 list.copy().

Обратите внимание, что эти методы делают not выводными эквивалентными результатами для любого ввода, отличного от списков. Все они работают для разрезаемых объектов, некоторые работы для любого итерабельного, но только copy.copy() работает для любого объекта Python.


Вот код тестирования для заинтересованных сторон ( Шаблон отсюда ):

import timeit

COUNT = 50000000
print("Array duplicating. Tests run", COUNT, "times")
setup = 'a = [0,1,2,3,4,5,6,7,8,9]; import copy'

print("b = list(a)\t\t", timeit.timeit(stmt='b = list(a)', setup=setup, number=COUNT))
print("b = copy.copy(a)\t\t", timeit.timeit(stmt='b = copy.copy(a)', setup=setup, number=COUNT))
print("b = a.copy()\t\t", timeit.timeit(stmt='b = a.copy()', setup=setup, number=COUNT))
print("b = a[:]\t\t", timeit.timeit(stmt='b = a[:]', setup=setup, number=COUNT))
print("b = a[0:len(a)]\t", timeit.timeit(stmt='b = a[0:len(a)]', setup=setup, number=COUNT))
print("*b, = a\t", timeit.timeit(stmt='*b, = a', setup=setup, number=COUNT))
print("b = []; b.extend(a)\t", timeit.timeit(stmt='b = []; b.extend(a)', setup=setup, number=COUNT))
print("b = []\nfor item in a: b.append(item)\t", timeit.timeit(stmt='b = []\nfor item in a:  b.append(item)', setup=setup, number=COUNT))
print("b = [i for i in a]\t", timeit.timeit(stmt='b = [i for i in a]', setup=setup, number=COUNT))

58
задан Jaap 12 September 2014 в 14:30
поделиться

1 ответ

Вы можете присвоить свой update объект запроса, который предотвращает обновление, если name уже присутствует в profile_set. В оболочке:

db.coll.update(
    {_id: id, 'profile_set.name': {$ne: 'nick'}}, 
    {$push: {profile_set: {'name': 'nick', 'options': 2}}})

Таким образом, это будет выполнять только $push для документа с сопоставлением _id и где нет элемента profile_set, где name есть 'nick'.

78
ответ дан JohnnyHK 18 August 2018 в 23:44
поделиться
  • 1
    как я могу принять это в upsert, я получил дублированную ошибку ключа ... – Zoozy 27 June 2013 в 05:28
  • 2
    мне нужно создать индекс profile_set.name? – MK Yung 23 December 2013 в 12:13
  • 3
    Если мне позже нужно изменить имя mick, это изменить существующий объект массива, а не добавлять новый. Есть ли способ сделать это в одной атомной операции обновления, которая по-прежнему соблюдает уникальное ограничение имени? – Anders Östman 27 October 2014 в 15:23
  • 4
    Повсюду я пошел решать проблемы мангуста или монго, @ ДжонниХК всегда спас меня. – Jinyoung Kim 30 March 2016 в 17:04
  • 5
    @JohnnyHK, что, если мне нужно переписать значение, если оно уже существует? – Alex Zhukovskiy 25 December 2017 в 14:43
Другие вопросы по тегам:

Похожие вопросы: