Highlight field type object or custom highlight

Hi all,

Sorry for my bad English

I have a problem with hightlight query search.


$params['body'][] = [
        'index' => [
            '_index' => 'my_index',
            '_type' => 'my_type',
        ]
];
$params['body'][] = [
        'id' => 1,
        'user' =>[
                  {
                        "name": "Nguyen Dinh",
                        "id": 2,
                        "language_id": 1
                  },
                  {
                        "name": "Trung Tuan",
                        "id": 2,
                        "language_id": 2
                  },
                  {
                        "name": "Trung Tuan",
                        "id": 2,
                        "language_id": 1
                  },
];

$jResult = $client->search([
                'index' => 'search',
                'type' => 'printers',
                'body' => [
                    'query' => [
                        'multi_match' => [
                            'query' => 'Tuan',
                            'type' => 'cross_fields',
                            'fields' => [ 'id', 'user.name']
                        ]
                    ],
                    'highlight' => [
                        'fields' => [
                           'id' => new \stdClass(),
                           'user.name' => new \stdClass(),
                        ]
                    ]
                ]
            ]);

Result highlight in hits

"highlight":{
     'user.name' => [
           'Trung <tag>Tuan</tag>',
           'Trung <tag>Tuan</tag>'
     ]
}

How I know
+ Trung <tag>Tuan</tag> with language_id 2
+ Trung <tag>Tuan</tag> with language_id 1
or custom result highlight.

Thanks a lot.

You would need to model these as nested documents for this to select only the relevant objects:

PUT test
PUT test/doc/_mapping
{
	"properties":{
		"user":{
			"type":"nested"
		}
	}
}
POST test/doc
{
	"id":1,
	"user":[
				  {
						"name": "Nguyen Dinh",
						"id": 2,
						"language_id": 1
				  },
				  {
						"name": "Trung Tuan",
						"id": 2,
						"language_id": 2
				  },
				  {
						"name": "Trung Tuan",
						"id": 2,
						"language_id": 1
				  }
   ]
}

POST test/_search
{
   "query": {
	  "nested": {
		 "path": "user",
		 "query": {
			"match": {
			   "user.name": "Trung "
			}
		 },
		 "inner_hits": {
			"highlight": {
			   "fields": {
				  "user.name": {}
			   }
			}
		 }
	  }
   }
}
1 Like

Hi Mark_Harwood,

Thanks for your support.

Why your code just return 3 result in total 149 result, please see picture:

Now,
If I add field for body , please see code below:

$params['body'][] = [
        'id' => 1,
        'type" => "Client Platform"
        'user' =>[
                  {
                        "name": "Nguyen Dinh",
                        "id": 2,
                        "language_id": 1
                  },
                  {
                        "name": "Trung Tuan",
                        "id": 2,
                        "language_id": 2
                  },
                  {
                        "name": "Trung Tuan",
                        "id": 2,
                        "language_id": 1
                  },
        ],
        'project' => [
                  {
                      "name": "food one",
                      'id':  1
                  },
                  {
                      "name": "food two",
                      'id':  2
                  },
                  {
                      "name": "food three",
                      'id':  3
                  }
         ]
];

I need query in 3 field : ['type', 'user.name', 'project.name'] with "type": 'cross_fields'

How I can add path for query nested .

I was tried path is a array but not not correctly.
"path": ["user",'project']

Please help me idea.

Thanks.

Without seeing your docs or your query there is not way for me to tell.
Take a look at the "explain" API [1] - it can tell you why a doc got a score but can also be used to show why a doc didn't match a given search

[1] What Is Relevance? | Elasticsearch: The Definitive Guide [2.x] | Elastic

1 Like

I was understood Why a Document Matched


You have any idea for 2nd question above .

I add one or more fields. EX (add one field : project):

$params['body'][] = [
        'id' => 1,
        'type" => "Client Platform"
        'user' =>[
                  {
                        "name": "Nguyen Dinh",
                        "id": 2,
                        "language_id": 1
                  },
                  {
                        "name": "Trung Tuan",
                        "id": 2,
                        "language_id": 2
                  },
                  {
                        "name": "Trung Tuan",
                        "id": 2,
                        "language_id": 1
                  },
        ],
        'project' => [
                  {
                      "name": "food one",
                      'id':  1
                  },
                  {
                      "name": "food two",
                      'id':  2
                  },
                  {
                      "name": "food three",
                      'id':  3
                  }
         ]
];

I need query in 3 field : ['type', 'user.name', 'project.name'] with "type": 'cross_fields'
Show any field exist $query ($query is a text_search)

How I can add path for query nested or any idea.

Thanks :slight_smile:

If you have declared in your mappings that a section of your documents is "nested" then you need to also declare query clauses that address those sections inside of a "nested" query clause as shown in my example.

If your request needs more than one "nested" query clause these can be listed in the "must" or "should" arrays inside a "bool" query .

1 Like

My setting

$params = [
            'index' => 'search',
            'body' => [
                'settings' => [
                    'analysis' => [
                        'analyzer' => [
                            'ngram_analyzer' => [
                                'type' => 'custom',
                                'tokenizer' => 'my_ngram_tokenizer', //'standard',
                                'filter' => ['word_delimiter_character', 'lowercase']
                            ]
                        ],
                        'tokenizer' => [
                            'my_ngram_tokenizer' => [
                                'type' => 'edge_ngram',
                                'min_gram' => 2,
                                'max_gram' => 100,
                                'token_chars' => ["letter", "digit"]
                            ]
                        ],
                        'filter' => [
                            'word_delimiter_character' => [
                                'type' => 'word_delimiter',
                                'split_on_numerics' => false,
                                'split_on_case_change' => false,
                                'generate_word_parts' => true,
                                'generate_number_parts' => true,
                                'catenate_all' => false
                            ]
                        ]
                    ]
                ],
                'mappings' => [
                    'printers' => [
                        'properties' => [
                            'type' => ['type' => 'string'],
                            'manual_s' => [
                                'type' => 'nested'
                            ],
                            'software_s' => [
                                'type' => 'nested'
                            ],
                            'solution_s' => [
                                'type' => 'nested'
                            ]
                        ]
                    ]
                ]
            ]
        ];

My query search :

$jResult = $client->search([
                'index' => 'search',
                'type' => 'books',
                'body' => [
                    'from' => $iFrom,
                    'size' => $iSize,
                    'query' => [
                        'bool' => [
                            'should' => [
                                'nested' => [
                                    "path" => "user",
                                    "query" => [
                                        "multi_match" => [
                                            'query' => "Tuan food",
                                            'fields' => ['user.name']
                                        ]
                                    ],
                                    "inner_hits" => [
                                        "highlight" => [
                                           "fields" => [
                                                "user.name" => new \stdClass()
                                            ]
                                        ]
                                    ]
                                ],
                                'nested' => [
                                    "path" => "project",
                                    "query" => [
                                        "multi_match" => [
                                            'query' => "Tuan food",
                                            'fields' => ['project.name']
                                        ]
                                    ],
                                    "inner_hits" => [
                                        "highlight" => [
                                           "fields" => [
                                                "project.name" => new \stdClass()
                                            ]
                                        ]
                                    ]
                                ]
                            ]
                        ]
                    ]
                ]
            ]);

But result not correct.
Where am I wrong ?

Hard to say. Your last example is missing any docs. The query is referring to fields that are not part of the mapping.
The best way to get help is to post the smallest reproducible example of an issue. If you use Sense or Curl to create a mapping, docs and a query that illustrate the problem they can be shared here and we can run them.

Hi Mark Harwood,

My code:

DELETE /books

    PUT /books
    {
       "settings": {
          "analysis": {
             "analyzer": {
                "ngram_analyzer": {
                   "ngram_analyzer": "custom",
                   "tokenizer": "my_ngram_tokenizer",
                   "filter": [
                      "word_delimiter_character",
                      "lowercase"
                   ]
                }
             },
             "tokenizer": {
                "my_ngram_tokenizer": {
                   "type": "edge_ngram",
                   "min_gram": 2,
                   "max_gram": 100,
                   "token_chars": [
                      "letter",
                      "digit"
                   ]
                }
             },
             "filter": {
                "word_delimiter_character": {
                   "type": "word_delimiter",
                   "split_on_numerics": false,
                   "split_on_case_change": false,
                   "generate_word_parts": true,
                   "generate_number_parts": true,
                   "catenate_all": false
                }
             }
          }
       },
       "mappings": {
          "post": {
             "properties": {
                "name": {
                   "type": "string",
                   "analyzer": "ngram_analyzer"
                },
                "author": {
                   "type": "nested",
                   "properties": {
                      "name": {
                         "type": "string",
                         "analyzer": "ngram_analyzer"
                      }
                   }
                },
                "project": {
                   "type": "nested",
                   "properties": {
                      "name": {
                         "type": "string",
                         "analyzer": "ngram_analyzer"
                      }
                   }
                }
             }
          }
       }
    }

    PUT /books/post/1
    {
        "id":9,
        "title": "Bai bao hay nhat",
        "author":[
            {
                "name": "Cho Nguoi Noi Ay",
                "language_id": 1,
                "country_id": 1
            },
            {
                "name": "Cho Nguoi Noi Ay",
                "language_id": 2,
                "country_id": 2
            }
        ],
        "project":[
            {
                "name": "Cho san xuat",
                "language_id": 3,
                "country_id": 3
            },
            {
                "name": "Nguoi hung",
                "language_id": 3,
                "country_id": 3
            }
        ]
    }

    PUT /books/post/2
    {
        "id":10,
        "title": "Doanh nhan",
        "author" :[
            {
                "name": "Cho Nguoi Noi Ay",
                "language_id": 1,
                "country_id": 1
            },
            {
                "name": "Cho Em Trong Dem",
                "language_id": 2,
                "country_id": 2
            }
        ],
        "project":[
            {
                "name": "That Khong The Tin",
                "language_id": 3,
                "country_id": 3
            },
            {
                "name": "chong hung",
                "language_id": 3,
                "country_id": 3
            }
        ]
    }
    }
POST books/post/_search
    {
       "query": {
           "bool":{
               "should": [
                {
                    "nested": {
                        "path": "author",
                        "query": {
                            "multi_match": {
                                "query":"oanh",
                                "type":"cross_fields",
                                "fields":["author.name"]
                            }
                        },
                        "inner_hits" : {
                            "highlight" : {
                                "fields" : {
                                    "author.name" : {}
                                }
                            }
                        }
                    }
                },
                {
                    "nested": {
                        "path": "project",
                        "query": {
                            "multi_match": {
                                "query":"oanh",
                                "type":"cross_fields",
                                "fields":["project.name"]
                            }
                        },
                        "inner_hits" : {
                            "highlight" : {
                                "fields" : {
                                    "project.name" : {}
                                }
                            }
                        }
                    }
                },
                {
                    "multi_match" : {
                        "query" : "oanh",
                        "type" : "cross_fields",
                        "fields" : ["title"]
                    }
                }
                ]
           }
       }
    }

I have a new problem :).
I need search same keyword.

I search with keyword "oanh" but no result.

You can see document /books/post/2 have "title": "Doanh nhan"

Exist key work oanh

How I can custom so have result.

Thanks,

Your mapping talks about "name" with ngram analyzer but your docs contain "title" which is not the ngram analyzer

1 Like

Thanks Mark,
I was fix my problem