Как проиндексировать неизвестные поля известного поля в PyMongo? - PullRequest
0 голосов
/ 22 декабря 2018

Я пытаюсь найти уникальные слова в миллионах твитов, а также хочу сохранить место, где появляется каждое слово.В дополнение к этому, я также группирую слова по их начальным буквам.Вот пример кода:

from pymongo import UpdateOne
# connect to db stuff
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({"initial": initial}, {"$inc": {"count": 1}, "$push": {"words.%s" % word: ret}}, upsert=True)
    commands.append(command)
    if len(commands) % 1000 == 0:
        db.tweet_words.bulk_write(commands, ordered=False)
        commands = []

Однако анализировать все эти твиты слишком медленно.Я предполагаю, что моя проблема возникает из-за того, что я не использую индекс для поля words.

Вот пример выходных документов:

{
    initial: "t"
    count: 3,
    words: {
        "the": [{"tweet_id": <some-tweet-id>, "pos": (2, 5)}, 
                {"tweet_id": <some-other-tweet-id>, "pos": (9, 12)}]
        "turkish": [{"tweet_id": <some-tweet-id>, "pos": (5, 11)}]
    }
}

Я пыталсясоздать индексы, используя следующие коды (безуспешно):

db.tweet_words.create_index([("words.$**", pymongo.TEXT)])

или

db.tweet_words.create_index([("words", pymongo.HASHED)])

У меня есть ошибки типа add index fails, too many indexes for twitter.tweet_words или key too large to index.Есть ли способ сделать это с индексами?Или должен изменить мой подход к проблеме (может быть, изменить дизайн БД)?

1 Ответ

0 голосов
/ 23 декабря 2018

Чтобы быть проиндексированным, вам нужно хранить ваши динамические данные в значениях объектов, а не ключей.Поэтому я бы посоветовал вам переработать схему, чтобы она выглядела так:

{
    initial: "t"
    count: 3,
    words: [
        {value: "the", tweets: [{"tweet_id": <some-tweet-id>, "pos": (2, 5)}, 
                                {"tweet_id": <some-other-tweet-id>, "pos": (9, 12)}]},
        {value: "turkish", tweets: [{"tweet_id": <some-tweet-id>, "pos": (5, 11)}]}
    ]
}

Который вы могли бы затем индексировать как:

db.tweet_words.create_index([("words.value", pymongo.TEXT)])
...