Hmm.. understood.
What I was trying to do, is leave the implementation as generic as possible.
I need to understand if I should limit the search capabilities granted to
users, or keep it as general as it is.
Let's say I have a database called 'mail' in my MongoDB cluster, and there
is a collection (table) named 'mailbox' inside of it.
Each object in this collection holds a mailbox, and also includes it's
aliases (real world example from my mail server):
{
"_id" : ObjectId(REDACTED),
"username" : "[email protected]",
"password" : "REDACTED",
"name" : "Hamid Maadani",
"maildir" : "[email protected]/",
"quota" : REDACTED,
"local_part" : "hamid",
"domain" : "dexo.tech",
"created" : ISODate("2016-11-07T21:07:21.000Z"),
"modified" : ISODate("2017-05-02T22:10:00.000Z"),
"active" : 1,
"alias" : [
{
"address" : "[email protected]",
"created" : ISODate("2016-11-07T21:04:16.000Z"),
"modified" : ISODate("2016-11-07T21:04:16.000Z"),
"active" : 1
},
{
"address" : "[email protected]",
"created" : ISODate("2016-11-07T21:04:16.000Z"),
"modified" : ISODate("2016-11-07T21:04:16.000Z"),
"active" : 1
}
]
},
{
"_id" : ObjectId(REDACTED),
"username" : "[email protected]",
"password" : "REDACTED",
"name" : "Site Admin",
"maildir" : "[email protected]/",
"quota" : REDACTED,
"local_part" : "admin",
"domain" : "dexo.tech",
"created" : ISODate("2017-04-12T22:24:17.000Z"),
"modified" : ISODate("2021-06-03T02:54:35.000Z"),
"active" : 1
}
Now, if I want to query for '[email protected]', or any of it's aliases, I would
use
this filter:
filter = {"$$or": [{"username":"%s"}, {"alias.address": "%s"}], "active": 1}
of course, this will return an entire JSON document. So I would use Mongo
projections to
limit it to just one key-value pair, in which case, the driver will only return
the value:
options = {"projection": {"_id": 0, "username": 1}}
The result of this filter-options combo, will be '[email protected]' whether you
search for
'[email protected]' or '[email protected]'
If I change the query to:
filter = {"active": 1}
and keep the same projection, it will return:
{"username":"[email protected]"}
{"username":"[email protected]"}
from what you just described, the result should be returned as:
[email protected],[email protected]
Correct?
That's the easy part. Question is, should I allow users to use the
filter/options combination
to search however they need? The reason I ask is, if someone uses this
projection:
{"projection": {"_id": 0, "username": 1, "name" : 1}}
The results would be:
{"username":"[email protected]", "name":"hamid"}
{"username":"[email protected]", "name":"admin"}
and I am unsure how to handle that. Limit it by requiring a key?
Or just return the string representation of the JSON documents for the user to
parse by
'jq' or similar utilities? Would there be a use case for that (postmap -q ... |
jq)?
I assume I should limit it by key, but want to run it by you guys first..
Regards
Hamid Maadani
June 15, 2022 2:43 PM, "Viktor Dukhovni" <[email protected]> wrote:
> On Wed, Jun 15, 2022 at 09:22:37PM +0000, Hamid Maadani wrote:
>
>> This is good, was unaware of the multi-row result standard.
>> How does this work with other DBs? for example, if you have two result sets:
>> { "name": "hamid", "value": "test" }
>> { "name": "viktor", "value": "test2" }
>
> Well, Postfix dictionaries cannot meaningfully consume structured data,
> you can return a single value, or a comma-separated list. If it is a
> list of email addresses, they should be stored in "external form"
> (RFC-5322 quoted) allowing robust parsing as a comma-separated list of
> such quoted forms).
>
> Thus "name" might be the key, and "value" the desired value column,
> so that a query for "hamid" would return "test", and a query for
> "viktor" would return "test2".
>
> But if the database also held:
>
> { "name": "devs", "value": "wietse" }
> { "name": "devs", "value": "viktor" }
> { "name": "devs", "value": "hamid" }
>
> then a query for "devs" would return:
>
> wietse,viktor,hamid
>
>> should it return as below?
>> hamid,test,viktor,test2
>
> So definitely not this, it makes no sense.
>
>> Regarding the 'db_common_expand' line, I used the same function used for the
>> SQL dict,
>> to support expansions like %s , %u and such for mongodb search filter, if
>> that makes sense.
>
> Yes, "%s", "%u" and "%d" are reasonably expected.
>
> You should also support the "domain" attribute to limit the keys sent to
> the database to just email addresses with a domain part matching one of
> the elements of that list.
>
> --
> Viktor.