0

I have some code which should return 5 matches from the search.

If I try the query in browser, I get 5 results:

http://localhost:9200/_search?q=Testing

If I user SENSE editor it also shows my 5 results:

Server=localhost:9200
POST _search
{
    "query": {
        "query_string": {
            "query": "Testing"
        }
    }
}

But my C# code in controller fails to get any match. What am I missing?

Uri localhost = new Uri("http://localhost:9200");
            var setting = new ConnectionSettings(localhost);
            setting.SetDefaultIndex("videos");
            var client = new ElasticClient(setting);

            var result = client.Search<SearchHint>(
                body => body.Query(
                    query => query.QueryString(
                        qs => qs.Query(keys))));

            var results = new SearchResults()
            {
                Results = result.Documents.ToList() <-- this has 0 items
            };

EDIT 1:

public class SearchHint
    {
        public string Id { get; set; }
        public string Title { get; set; }
        public int NumItems { get; set; }
        public bool IsList { get; set; }

        public SearchHint(string id, string title, int numItems, bool isList)
        {
            Id = id;
            Title = title;
            NumItems = numItems;
            IsList = isList;
        }
    }

EDIT 2: There are 4 types in the index (videos\list, videos\video, videos\author, videos\category). Any search should search all types not any particular type.

kheya
  • 7,546
  • 20
  • 77
  • 109
  • Can you please add the code for your `SearchHint` class and the mapping for the type you are searching for in your index? – Paige Cook May 19 '14 at 12:37

1 Answers1

1

I think the issue is related to the way that NEST is defaulting the types for your search. Unless you have specified and [ElasticType] attribute on your SearchHint class it will query Elasticsearch with the following url:

 /_all/searchhint/_search

Try adding the typename that corresponds to the type you are using in your index, to your class definition, like the following (replacing mytype with the appropriate value for your index. Also, if you fields on the indexed items do not match the default mapping conventions (camel cased) you will not get data populated.

 [ElasticType(Name = "mytype"]
 public class SearchHint
 {
       // Will map to field with name title in your index.
       //Use the following property to specify an alternate name
       //[ElasticProperty(Name="Title")]
       public string Title { get; set;}
 }

Please see NEST Documentation on Inference for an overview of how this all works.

Update: The previous only applies to searching within a single type. If you want to search across multiple types, then you will need to specify .AllTypes() on your search query and there is not a need to specify the [ElasticType] attribute on your class.

            var result = client.Search<SearchHint>(
                body => body
                  .AllTypes()
                  .Query(
                    query => query.QueryString(
                        qs => qs.Query(keys))));
Paige Cook
  • 22,415
  • 3
  • 57
  • 68
  • There are 4 types in the index (videos\list, videos\video, videos\author, videos\category). Any search should search all types not any particular type. – kheya May 19 '14 at 16:53
  • I need to know the type, id, title and numItems value from the index for each result. That way I can build the autocomplete list with proper hyperlinks. I was expecting that these will be automatically mapped when I call result.Documents.ToList() – kheya May 19 '14 at 19:28
  • If the id, title and numItems fields are all defined fields in each respective type, then they should map without issue. You can use the `results.HitsMetaData.Hits` collection that will give you a `Type` property that is the index type and `Source` property that will be a `SearchHint` object. – Paige Cook May 19 '14 at 19:41
  • _type and _id properties are in the index BUT category, owner, title, tags are in the source document. I see this if I try the query in browser "hits":[{"_index":"videos","_type":"list","_id":"1234","_score":0.76073027, "_source" : { "cat" : "People","ow" : "Bob","tgs" : ["Bob", "Song"],"ttl" : "Videos by Bob"} – kheya May 19 '14 at 19:43
  • results.HitsMetaData.Hits has correct values in Id, Type, Index and Score fields. But all properties in Source are null eventhough it is of type SearchHint. Also Version is null as well. – kheya May 19 '14 at 20:02
  • Solved it partially. I made the SearchHint class members name match exactly the way they are in the source document inside the index. Now I see them populated. But how do I get id and the type. They are outside of source document. – kheya May 19 '14 at 20:19
  • You will need to compose an object post search that combines the MetaData with the Source to get what you want. I would suggest using something like AutoMapper - https://github.com/AutoMapper/AutoMapper – Paige Cook May 20 '14 at 01:50