Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Querying Multiple Autocomplete fields #456

Closed
RWAust opened this issue Feb 6, 2014 · 2 comments
Closed

Querying Multiple Autocomplete fields #456

RWAust opened this issue Feb 6, 2014 · 2 comments

Comments

@RWAust
Copy link

RWAust commented Feb 6, 2014

Hi,

I seem to be having a problem getting my query to work on two fields that have been indexed with Autocomplete. The code below creates the new index and I'm interested in being able to search on MyField1 and MyField2 using the Auto Complete.

var createResult = client.CreateIndex("sample", index => index
                        .Analysis(analysis => analysis
                            .Analyzers(a => a
                                .Add(
                                    "autocomplete",
                                    new Nest.CustomAnalyzer()
                                    {
                                        Tokenizer = "edgeNGram",
                                        Filter = new string[] { "lowercase" }
                                    }
                                )
                            )
                            .Tokenizers(t => t
                                .Add(
                                    "edgeNGram",
                                    new Nest.EdgeNGramTokenizer()
                                    {
                                        MinGram = 1,
                                        MaxGram = 20
                                    }
                                )
                            )
                        )
                        .AddMapping<Document>(tmd => tmd
                            .Properties(props => props

                                .MultiField(p => p
                                    .Name(t => t.MyField1)                                        
                                    .Fields(tf => tf                                            
                                        .String(s => s
                                            .Name(t => t.MyField1)                                                
                                            .Index(Nest.FieldIndexOption.not_analyzed)
                                               )
                                        .String(s => s
                                            .Name(t => t.MyField1.Suffix("autocomplete"))                                                
                                            .Index(Nest.FieldIndexOption.analyzed)
                                            .IndexAnalyzer("autocomplete")
                                               )
                                           )
                                          )
                                .MultiField(p => p
                                    .Name(t => t.MyField2)
                                    .Fields(tf => tf
                                    .String(s => s
                                        .Name(t => t.MyField2)
                                        .Index(Nest.FieldIndexOption.not_analyzed)
                                            )
                                    .String(s => s
                                        .Name(t => t.MyField2.Suffix("autocomplete"))
                                        .Index(Nest.FieldIndexOption.analyzed)
                                        .IndexAnalyzer("autocomplete")
                                            )
                                        )
                                       )
                            )
                        )
                    );

I have a function

      public JsonResult Index(string searchString)
 {      
   result = ElasticClient.Search<Document>(s => s
                     .Index("sample")
                    .Type("documents")                                      
                    .Query(q => q                                                        
                        .Text(tq => tq                                              
                            .OnField(t => t.MyField1.Suffix("autocomplete"))
                            //.OnField(t => t.MyField2.Suffix("autocomplete"))
                            .QueryString(searchString)
                            )                                                        
                       )
                );
    return Json(result.Documents.ToList(), JsonRequestBehavior.AllowGet);
 }

If I comment out MyField2, I can search on autocompleted words for MyField1 and my drop-down box shows results I expect. Similarly, if I enable MyField2 and comment out MyField1, I can search on autocompleted words for MyField2 and my drop-down box shows results I expect.

The problem lies in submitting searchString that contains partial words (eg, partialWordMyField1 and partialWordMyField2) that match MyField1 AND MyFieled2. In this case, I enable the following:

 .OnField(t => t.MyField1.Suffix("autocomplete"))
 .OnField(t => t.MyField2.Suffix("autocomplete"))

in the above Search.

The results I get from the above Search suggest an OR condition is actually occurring.

To account for this, I insert the word AND between partialWordMyField1 and partialWordMyField2 to give a modifiled searchString:

searchString = partialWordMyField1 AND partialWordMyField2;

but this does not change the result.

I have also tried:

  result = ElasticClient.Search<Document>(s => s
                .Index("sample")
                .Type("documents")

                .Query(q => q                            
                        .MultiMatch(mm => mm
                            .OnFields(t => t.CompanyName.Suffix("autocomplete"),
                                    t => t.PostCode.Suffix("autocomplete"))

                           .QueryString(searchStringModified)
                           )
                           )                                                                                 
                       )
            );

But the result is much the same in that I'm not getting results that contains only partialWordMyField1 AND partialWordMyField2.

Any help will be appreciated.

Thanks

@Mpdreamz
Copy link
Member

Mpdreamz commented Feb 6, 2014

You can write the query like so:

.Query(q => 
    q.Text(tq => tq                                              
        .OnField(t => t.MyField1.Suffix("autocomplete"))
        .QueryString(searchString)
    )                    
    && q.Text(tq => tq                                              
        .OnField(t => t.MyField2.Suffix("autocomplete"))
        .QueryString(searchString)
    )    
)

Calling OnField multiple times causes the last one to override the previous one.

Hope this helps!

@Mpdreamz Mpdreamz closed this as completed Feb 6, 2014
@RWAust
Copy link
Author

RWAust commented Feb 6, 2014

That really helped and worked thank you.

What I am now finding is that query is not finding entries where the search word is in the middle of the MyField1.

Suppose MyField1 represents moview titles and MyField2 represents the year the movie was released

Suppose we have the following example:

MyField1 = Star Wars Episode VI: Return of the Jedi
MyField2 = 1983

If I perform the above query with

searchString = sta 198

I get the correct result.

However, if

searchString = war 198

no results come back.

What do I need to do to be able to search in the middle of a field?

Thanks again for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants