Индексирование не так быстро, как ожидалось для поиска в MongoDB? - PullRequest
0 голосов
/ 24 декабря 2018

У меня есть уникальная коллекция слов 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есть ли разрешимое узкое место в моем коде?Или это так же хорошо, как получает?

...