开发者

mongodb python get the element position from an array in a document

I use python + mongodb to store some item ranking data in a collection called 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) 
  ]
}

Now my problem is, I want to make a history ranking chart for itemA. And according to the $ positional operator, the query should be somet开发者_运维知识库hing like this:

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

And the $ operator doesn't work.

Any other possible solution to this?


The $ positional operator is only used in update(...) calls, you can't use it to return the position within an array.

However, you can use field projection to limit the fields returned to just those you need to calculate the position in the array from within 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]

In this (admittedly trivial) example, returning just a subset of fields may not show much benefit; however if your documents are especially large, doing may show performance improvements.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜