jstedfast/MailKit

A Link for search Message Text would be nice

NilsHoyer opened this issue · 14 comments

With MailFolder.Search, I can specify a Text, which will be used for UID SEARCH. A link inside your documentation with a detailed description would be nice, I think. Maybe to the related RFC diretely...

If I use a SearchQuery, with a "{" inside, i didn't find a mailnwith the related Subject. But until now, I didn't verify, if this was my mistake.

Additional, If I ready your API description with my Android Smartphone, it's very small. I believe, you did not offer mobile version.

... I don't need your assistance, I will find all I need Someehre, I believe. But I wanted to let you know my how you could improve you dicumantion Fürther more. Please excuse me, if you feel bithed with my posting.

The specification for the SEARCH command can be found in rfc3501, section 6.4.4 but it's probably not going to be super helpful (unfortunately).

Most IMAP servers seem to use some sort of "word index" that is used for body text searches, so it's not very accurate. This is likely done to make it "fast", otherwise it would be excruciatingly slow to do an exact text search over an entire folder of messages.

This likely is what causes searches with punctuation to fail for you, but you won't find any clue about this in the IMAP docs.

I haven't actually tried reading docs on my phone, but I would not be surprised if it wasn't very optimal - I use the Sandcastle Help File Builder to generate the web docs. Unfortunately, until that Visual Studio extension adds support for generating HTML for mobile devices, MimeKit/MailKit docs probably won't look very nice on mobile devices, either :(

I've attached the log.

If I'm right, the problem based on the double quotes for the UID SEARCH command. If I search about "HelloTest", it works without the quotes. But with "Hello Test" it fails, since now MailKit adds the quotes. I believe, this is a server bug.
Imap.log

Yea, I'm pretty sure that you are correct that this is a server bug.

I've updated the API Reference Manual to include a link to the appropriate specification that defines the search term.

Die you know a good free IMAP server for local developing under Windows?

Unfortunately, I don';t know of a good one for Windows that is easy to setup. I usually use Dovecot on Mac/Linux if I need to set one up.

Last week, I tried the following IMailFolder.Search method:
https://mimekit.net/docs/html/M_MailKit_Net_Imap_IImapFolder_Search.htm

Unfortunately, I was to stupid to find them inside VS 2022 after installing your NuGet Package 😢.

(Still, I have problems understanding the SeaechQuery class, using multiple AND and OR.)

The And and Or methods can be used in 2 ways:

// Both of these are identical:
var query1 = SearchQuery.SubjectContains ("subject").And (SearchQuery.FromContains ("Nils"));
var query2 = SearchQuery.And (SearchQuery.SubjectContains ("subject"), SearchQuery.FromContains ("Nils"));

The Or method can be used in exactly the same ways.

The SearchQuery APIs essentially build an expression tree if that concept is at all familiar to you.

Does that answer your question? Or what are you struggling with? Perhaps I can try to explain it.

Thank you for your offer to assist me, I'm happy about this, since I'm too stupid to find a solution by myself.

I have six expressions: Expr1, Expr2, ... Expr6.

In C# I would use this

if (Expr1 && Expr2 || Expr3 && Expr4 || Expr5 && Expr6)
    ...

I've tried to realize this with MailKit on this way:

var searchQuery =
    SearchQuery.SubjectContains(Expr1).And(SearchQuery.SubjectContains(Expr2))
        .Or(SearchQuery.SubjectContains(Expr3).And(SearchQuery.SubjectContains(Expr4))
        .Or(SearchQuery.SubjectContains(Expr5).And(SearchQuery.SubjectContains(Expr6))));

For me, it is important, that the AND (&&) will be handled before the OR (||).

Inside the log, I found this line:

C: A00000006 UID SEARCH OR (SUBJECT "Expr1" SUBJECT "Expr2") OR (SUBJECT "Expr3" SUBJECT "Expr4") (SUBJECT "Expr5" SUBJECT "Expr6")

I would expect this one (but I'm not a IMAP professional, so maybe I'm wrong):

C: A00000006 UID SEARCH (SUBJECT "Expr1" SUBJECT "Expr2") OR (SUBJECT "Expr3" SUBJECT "Expr4") OR (SUBJECT "Expr5" SUBJECT "Expr6")

MailKit's command is correct and matches you pseudo-code if-statement.

IMAP's SEARCH command uses "prefix" notation (as opposed to "infix"). In other words:

OR EXPR1 EXPR2 would map to if (EXPR1 || EXPR2) in C# syntax.

If we then expand this out a bit more to something a little closer to your query:

OR EXPR1 OR EXPR2 EXPR3 would map to if (EXPR1 || (EXPR2 || EXPR3))

So if we take then look at the SEARCH command that MailKit is sending:

C: A00000006 UID SEARCH OR (SUBJECT "Expr1" SUBJECT "Expr2") OR (SUBJECT "Expr3" SUBJECT "Expr4") (SUBJECT "Expr5" SUBJECT "Expr6")

This would map to:

if (
    (Subject.Contains ("Expr1") && Subject.Contains ("Expr2"))
    ||
    (
        (Subject.Contains ("Expr3") && Subject.Contains ("Expr4"))
        ||
        (Subject.Contains ("Expr5") && Subject.Contains ("Expr6"))
    ))

... so the problem is again the server, I'm using on my local Windows system.

Thank you for checking my code and your detailed description.