0

Today i have a database with all users, now i want to copy the users to elasticsearch. When i search users in the db, i use 2 sql queries,

  • SELECT * FROM Users WHERE Username LIKE 'An%' (for autocomplete)
  • SELECT * FROM Users WHERE Username LIKE '%An%' (for free text search)

Now i want to do the same thing in elasticsearch. This is what i have:

 public static string IndexName => "users";


 public static List<UserInfo> FindUsersStartsWith(string name, int pageSize, int currentPage,
        ref long unitItems)
    {
            var Result = Client.Search<UserInfo>(s => s
                .Index(IndexName)
                .Query(q => q
                    .Match(m => m
                        // specify the field
                        .Field(f => f.UserName)
                        .Query(name)
                    )
                )
                .Size(pageSize)
                .From((currentPage - 1) * pageSize)
                );

            unitItems = Result.Total;
            return Result.Documents.ToList();            
    }

 public static List<UserInfo> FindUsersContains(string name, int pageSize, int currentPage,
        ref long unitItems)
    {
            var Result = Client.Search<UserInfo>(s => s
                .Index(IndexName)
                .Query(q => q
                    .Match(m => m
                        // specify the field
                        .Field(f => f.UserName)
                        .Query(name)
                    )
                )
                .Size(pageSize)
                .From((currentPage - 1) * pageSize)
                );

            unitItems = Result.Total;
            return Result.Documents.ToList();            
    }

    public static void SetUser(UserInfo ui)
    {
            if (!client.IndexExists(IndexName).Exists)
            {
                client.CreateIndex(IndexName);
            }

            Client.Update<UserInfo, UserInfo>
                (DocumentPath<UserInfo>
                    .Id(ui.UserNr), descriptor => descriptor.Doc(ui).DocAsUpsert().Refresh()
                );

    }

[Serializable, ElasticsearchType(IdProperty = "UserNr")]
public class UserInfo
{
    public string UserName { get; set; }
    public string Name { get; set; }
    public string Avatar { get; set; }
    public int UserNr { get; set; }
}

Edit: My idea is to have 2 functions. One where i can search on users that starts with, "An" (upper- or lowercase doesn't matter) and returns users like "Andy", not "Ronan". The other function will return all users that contains "An" (upper- or lowercase doesn't matter).

4
  • Does it need to be exactly An (case sensitive)? Should An only be found at the start of word boundaries e.g. Andy, or can it be found anywhere within a word e.g. Ronan? Please edit your question to include any such restrictions, as this may affect the approach to take Commented Mar 9, 2016 at 22:41
  • 1
    Additionally, ConnectionSettings and ElasticClient can be singletons and live for the lifetime of your application; you can construct them at startup and reuse them and also check and create the index at startup too :) Commented Mar 9, 2016 at 23:57
  • 2
    For the autocomplete, did you consider the completion suggester/field? If you don't want another field, consider the match_phrase_prefix query For your search, the wildcard may serve you well. Commented Mar 10, 2016 at 12:53
  • @RussCam I updated my question with more information. Commented Mar 10, 2016 at 20:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.