質問

I have a MongoDB structure which currently looks like this:

[campaigns] => Array (
    [0] => Array (
        [campaign_id] => 4e8cba7a0b7aabea08000006
        [short_code] => IHEQnP
        [users] => Array (
        )
    )
    [1] => Array (
        [campaign_id] => 4e8ccf7c0b7aabe508000007
        [short_code] => QLU_IY
        [users] => Array (
        )
    )
)

What I would like to be able to do, is search for the short code, and just have the relevant array returned. I initially tried:

db.users.find({'campaigns.short_code':'IHEQnP'}, {'campaigns.campaign_id':1})

However that returns all the arrays, as opposed to just the one (or field) that I want.

Is there a way in Mongo to get the correct array (or even field associated with the array)? Or is that something I would have to do on the server? Am using the lithium framework to retrieve the results (in case it helps).

Thanks in advance :)

Dan

役に立ちましたか?

解決

When you use a criteria like campaigns.short_code you are still searching the collection, the campaigns is just a property of a document, your find returns documents. So given this structure you can not achieve what you want directly by a query.

Arrays in MongoDb can be sliced, but not sorted:

db.users.find({}, {campaigns: { $slice : 1}})

This would give you the first campaign, but as you cant sort it so IHEQnP is at top its of no help in this situation. Read more here.

You could however filter this quite simple in Lithium after retrieving the full document:

$id = 'id to match against';
$result = $user->campaigns->find(function($model) use ($id) {
    return $model->campaign_id === $id
});

See docs for Entity::find here

My solution would be to keep it in User if the amount of campaigns is low (fast to sort and filter in PHP as long as document size isnt too big). If this is expected to grow then look at moving it to its own model/collection or re-think how you modelled your data.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top