[SERVER-1248] Should have an $* array-key-wildcard operator Created: 17/Jun/10  Updated: 15/Feb/13  Resolved: 26/Sep/12

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: phpMoAdmin Assignee: Unassigned
Resolution: Duplicate Votes: 9
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-267 Wildcard support in index/query/proje... Backlog
Participants:

 Description   

As far as I can tell there is no way to find an object containing a value in a subarray if you do not know the exact array-key path, so if the following were a collection of orders you cannot find all orders by unit ID without modifying the schema:

array(
'_id' => 213,
'units' = array(
0 => array('id' => 5, 'color' => 'red'),
1 => array('id' => 3, 'color' => 'blue'),
2 => array('id' => 8, 'color' => 'polka dot'),
3 => array('id' => 9, 'color' => 'green')
)
);

array(
'_id' => 456,
'units' = array(
0 => array('id' => 8, 'color' => 'purple'),
1 => array('id' => 2, 'color' => 'yellow')
)
);

We should be able to do something like:

$find = array('units.$*.id' => 8);
$col->find($find);

Assuming $* would be a wildcard operator that covers any key within the array



 Comments   
Comment by Scott Hernandez (Inactive) [ 26/Sep/12 ]

This seems to be a dup of SERVER-267. Please let us know otherwise.

Comment by Glenn Maynard [ 02/Apr/12 ]

This is really requesting a feature for searching documents and doesn't have anything to do with arrays. I think the OP was confused because PHP conflates key/value dictionaries and arrays, which is confusing for people whose first language is PHP.

This has parallels with multikey searching for arrays.

See also SERVER-5463.

Comment by Szabolcs Szász [ 02/Nov/11 ]

Yet another use case (a taxonomy "poly-tree").

Currently it's implemented as:

taxon:

{ 'parent': 'taxon0' }

// when all sources agree
or
taxon: { 'parent':

{ 'source1': 'taxon1', 'source2': 'taxon2' }

} // when sources disagree

But, alas, I can't seem to just get 'taxon1' and/or 'taxon2' regardless of source (1 or 2) in MongoDB.

Instead, I fear I might need to change the data model to:

taxon: { 'parent' {

{ 'source': 'source1', 'parent' => 'taxon1' }

,

{ 'source': 'source2', 'parent' => 'taxon2' }

}
}

which would not only be less sexy, but would mean lots of code changes, too, and would also put MongoDB to the "syntactic bottleneck" role instead of PHP.

Comment by Justin Shanks [ 25/Mar/11 ]

For my example, our objects in our content collection look like this:
_id: 12345678,
channels: {
print_issue: {
string_identifierA:

{ channel: 'MAR11', section: 'new_products', ... }

,
string_identifierB:

{ channel: 'APR11', section: 'new_products', ... }

}
}

I would like to query it like this

db.content.find(

{'channels.print_issue.$.channel': 'MAR11'}

);

I do realize if I took the 'string_identifier' out as the key of the object, put it into the sub object, and changed 'print_issue' to a normal array, that I could do a query like this:

db.content.find(

{'channels.print_issue.channel': 'MAR11'}

);

But I'd prefer to not modify my object format just for mongo inserts since the object format is used in the same way over multiple applications/api's as I'm sure is the case for many people who want or expect this functionality when considering mongo.

Comment by phpMoAdmin [ 26/Dec/10 ]

Hi Benjamin,

If your subkeys are consistent (they are always "text") then you can just skip the definition of the preceding variable-keys:

find(

{ "log.msg.text": ........ }

The issue in this ticket only applies if your subkey's vary and cannot be defined in the query.

Comment by Benjamin Menküc [ 25/Dec/10 ]

I have a similar problem.
My database looks like
{
"log": {
"0": {
"msg":

{ "text": "text1)" }


},
"1": {
"msg":

{ "text": "text2" }


}
}

I want to make a query on "text" for every msg in the array by using regexps (i need it that way). I tried:
find({$where:"/^text/.test(this.log.msg.text)"})
which doesnt work.
Is there any solution for this?
BTW: this was tested using the mongoconsole front-end.

regards,
Benjamin

Comment by John Crenshaw [ 30/Oct/10 ]

I sort of expected to be able to do something similar, except I expected to be able to use the $ operator here. I.E. units.$.id.

In some respects, this is less of a request for new functionality, and more of a request for a more logical and memorable syntax for querying arrays.

If $elemMatch were enhanced to work with objects, the $ operator could be used as shorthand for $elemMatch, and would also work for objects (which is what you have in the timestamp case shown).

Extending $elemMatch would additionally help alleviate some of the issues with arrays and PHP (it's too easy to accidentally break the numbering, resulting in an "object" being stored where an "array" is expected, and some operations stop working.) It appears that the discrepancy between "arrays" and "objects" (especially for PHP) may actually be at the root of this request, and blurring the lines so that it doesn't matter so much may fix the real need here.

Comment by phpMoAdmin [ 18/Jun/10 ]

Karoly, you are in-fact correct for the example that I posted, but the issue still exists for an array without any identifiable subkey.

In the next schema example, how would you search for a document with the "blueScarf.jpg" image if the arraykey is an unknown timestamp?

[_id] => 1
[img] => Array (
[1276297762] => greenPlant.jpg
)

[_id] => 2
[img] => Array (
[1276291209] => redScarf.jpg
[1276299876] => blueScarf.jpg
)

[_id] => 3
[img] => Array (
[1276290193] => purpleCar.jpg
[1276299233] => yellowCar.jpg
[1276290971] => whiteCar.jpg
)

Comment by Karoly Negyesi [ 17/Jun/10 ]

just query on units.id , it works, and don't forget $elemMatch if you are querying on two.

Generated at Thu Feb 08 02:56:30 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.