Mongodb Python получить позицию элемента из массива в документе - PullRequest
2 голосов
/ 12 июля 2011

Я использую python + mongodb для хранения некоторых данных ранжирования предметов в коллекции под названием chart

{
  date: date1,
  region: region1,
  ranking: [
    {
      item: bson.dbref.DBRef(db.item.find_one()),
      price: current_price,
      version: '1.0'
    },
    {
      item: bson.dbref.DBRef(db.item.find_another_one()),
      price: current_price,
      version: '1.0'
    },
    .... (and the array goes on) 
  ]
}

Теперь моя проблема в том, что я хочу составить таблицу ранжирования истории для itemA. И согласно позиционному оператору $ , запрос должен выглядеть примерно так:

db.chart.find( {'ranking.item': bson.dbref.DBRef('item', itemA._id)}, ['$'])

И оператор $ не работает.

Любое другое возможное решение этой проблемы?

1 Ответ

3 голосов
/ 12 июля 2011

Позиционный оператор $ используется только в вызовах update(...), его нельзя использовать для возврата позиции в массиве.

Однако вы можете использовать проекцию поля , чтобы ограничить поля, возвращаемые только теми, которые вам нужны для вычисления позиции в массиве из Python:

db.foo.insert({
'date': '2011-04-01',
'region': 'NY',
'ranking': [
{ 'item': 'Coca-Cola', 'price': 1.00, 'version': 1 },
{ 'item': 'Diet Coke', 'price': 1.25, 'version': 1 },
{ 'item': 'Diet Pepsi', 'price': 1.50, 'version': 1 },
]})

db.foo.insert({
'date': '2011-05-01',
'region': 'NY',
'ranking': [
{ 'item': 'Diet Coke', 'price': 1.25, 'version': 1 },
{ 'item': 'Coca-Cola', 'price': 1.00, 'version': 1 },
{ 'item': 'Diet Pepsi', 'price': 1.50, 'version': 1 },
]})

db.foo.insert({
'date': '2011-06-01',
'region': 'NY',
'ranking': [
{ 'item': 'Coca-Cola', 'price': 1.00, 'version': 1 },
{ 'item': 'Diet Pepsi', 'price': 1.50, 'version': 1 },
{ 'item': 'Diet Coke', 'price': 1.25, 'version': 1 },
]})

def position_of(item, ranking):
    for i, candidate in enumerate(ranking):
            if candidate['item'] == item:
                    return i
    return None

print [position_of('Diet Coke', x['ranking'])
       for x in db.foo.find({'ranking.item': 'Diet Coke'}, ['ranking.item'])]

# prints [1, 0, 2]

В этом (по общему признанию тривиальном) примере возвращение только подмножества полей может не показать большой выгоды; однако, если ваши документы особенно большие, выполнение может показать улучшение производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...