У меня есть уникальная коллекция слов Twitter в моей базе данных.Документ внутри него имеет следующую форму:
{
_id: <some-object-id>,
initial: "t",
word: "the",
count: 986,
tweets: <position information for the given word>
}
Я пробовал следующие коды для создания индексов:
db.tweet_words.create_index([("word", pymongo.ASCENDING), ("initial", pymongo.ASCENDING)], background=True)
и
db.tweet_words.create_index("word", background=True)
и
db.tweet_words.create_index([("word", pymongo.HASHED)], background=True)
Хотя использование этих индексов помогло выполнить команду обновления быстрее, она все еще работает относительно медленно.Я думаю, что должен быть лучший способ.
Вот мои команды обновления:
from pymongo import UpdateOne
# connect to db stuff
# create indexing using one of the approaches above
commands = []
for word in words: # this is actually not the real loop I've used but it fits for this example
# assume tweet_id's and position is calculated here
initial = word[0]
ret = {"tweet_id": tweet_id, "pos": (beg, end)} # additional information about word
command = UpdateOne({"word": word, "initial": initial}, # use query {"word": word} only if one of bottom two indexing strategy is chosen
{
"$setOnInsert": {"initial": initial},
"$inc": {"count": 1},
"$push": {"tweets": ret},
},
commands.append(command)
if len(commands) % 1000 == 0:
db.tweet_words.bulk_write(commands, ordered=False)
commands = []
Вы можете найти реальный код здесь .
Вот вывод pprint(db.tweet_words.find({"word": word}).explain())
(не удалось придумать, как использовать метод объяснения на UpdateOne
или bulk_write
), когда в коллекции присутствует ~ 130k документов:
{'executionStats': {'allPlansExecution': [],
'executionStages': {'advanced': 1,
'alreadyHasObj': 0,
'docsExamined': 1,
'executionTimeMillisEstimate': 0,
'inputStage': {'advanced': 1,
'direction': 'forward',
'dupsDropped': 0,
'dupsTested': 0,
'executionTimeMillisEstimate': 0,
'indexBounds': {'initial': ['[MinKey, '
'MaxKey]'],
'word': ['["seval", '
'"seval"]']},
'indexName': 'word_1_initial_1',
'indexVersion': 2,
'invalidates': 0,
'isEOF': 1,
'isMultiKey': False,
'isPartial': False,
'isSparse': False,
'isUnique': False,
'keyPattern': {'initial': 1,
'word': 1},
'keysExamined': 1,
'multiKeyPaths': {'initial': [],
'word': []},
'nReturned': 1,
'needTime': 0,
'needYield': 0,
'restoreState': 0,
'saveState': 0,
'seeks': 1,
'seenInvalidated': 0,
'stage': 'IXSCAN',
'works': 2},
'invalidates': 0,
'isEOF': 1,
'nReturned': 1,
'needTime': 0,
'needYield': 0,
'restoreState': 0,
'saveState': 0,
'stage': 'FETCH',
'works': 2},
'executionSuccess': True,
'executionTimeMillis': 0,
'nReturned': 1,
'totalDocsExamined': 1,
'totalKeysExamined': 1},
'ok': 1.0,
'queryPlanner': {'indexFilterSet': False,
'namespace': 'twitter.tweet_words',
'parsedQuery': {'word': {'$eq': 'seval'}},
'plannerVersion': 1,
'rejectedPlans': [],
'winningPlan': {'inputStage': {'direction': 'forward',
'indexBounds': {'initial': ['[MinKey, '
'MaxKey]'],
'word': ['["seval", '
'"seval"]']},
'indexName': 'word_1_initial_1',
'indexVersion': 2,
'isMultiKey': False,
'isPartial': False,
'isSparse': False,
'isUnique': False,
'keyPattern': {'initial': 1,
'word': 1},
'multiKeyPaths': {'initial': [],
'word': []},
'stage': 'IXSCAN'},
'stage': 'FETCH'}},
'serverInfo': {'gitVersion': 'f288a3bdf201007f3693c58e140056adf8b04839',
'host': 'MostWanted',
'port': 27017,
'version': '4.0.4'}}
Isесть ли разрешимое узкое место в моем коде?Или это так же хорошо, как получает?