Need help adjusting elastic settings

Hello everyone, at the moment everything is almost fine, but there is a problem when the required string is not found through multi_match and due to the filter selects the wrong result. If the occurrence of the string is found, then the correct result is returned.
I'm using phpSdk but the configuration object structure is the same as natively described in the documentation.

[
    'index' => ProductIndexerService::INDEX,
    'body' => [
        'mappings' => [
            'properties' => [
                'id' => [
                    'type' => 'integer',
                ],
                'name' => [
                    'type' => 'text',
                    'analyzer' => 'snowball_analyzer',
                    'fields' => [
                        'ngram' => [
                            'type' => 'text',
                            'analyzer' => 'ngram_index_analyzer',
                            'search_analyzer' => 'ngram_search_analyzer'
                        ]
                    ]
                ],
                'product_no' => [
                    'type' => 'keyword'
                ],
                'category_id' => [
                    'type' => 'integer'
                ],
                'marketplace_id' => [
                    'type' => 'integer'
                ],
                'min_price' => [
                    'type' => 'double'
                ],
                'product_status' => [
                    'type' => 'integer'
                ],
                'vendors' => [
                    'type' => 'nested',
                    'properties' => [
                        'vendor_id' => ['type' => 'integer'],
                        'vendor_sku' => ['type' => 'keyword'],
                        'vendor_marketplaces' => [ 'type' => 'integer']
                    ]
                ]
            ],
        ],
        'settings' => [
            'analysis' => [
                'analyzer' => [
                    'ngram_index_analyzer' => [
                        'type' => 'custom',
                        'tokenizer' => 'standard',
                        'filter' => [
                            'stopwords',
                            'asciifolding',
                            'lowercase',
                            'app_ngram'
                        ]
                    ],

                    'ngram_search_analyzer' => [
                        'type' => 'custom',
                        'tokenizer' => 'standard',
                        'filter' => [
                            'asciifolding',
                            'lowercase',
                            'stopwords'
                        ]
                    ],
                    'snowball_analyzer' => [
                        'type' => 'custom',
                        'tokenizer' => 'standard',
                        'filter' => [
                            'asciifolding',
                            'lowercase',
                            'stopwords',
                            'snowball'
                        ]
                    ]
                ],

                'filter' => [

                    'snowball' => [
                        'type' => 'snowball',
                        'language' => 'English'
                    ],

                    'stopwords' => [
                        'type' => 'stop',
                        'stopwords' => '_english_'
                    ],

                    'app_ngram' => [
                        'type' => 'ngram',
                        'min_gram' => 3,
                        'max_gram' => 4
                    ]

                ]
            ],
        ],
    ],
]

The search object now looks like this

[
    'index' => ProductIndexerService::INDEX,
    'body' => [
        'size' => 50,
        'query' => [
            'bool' => array_filter([
                'should' => array_merge(array_filter(isset($params['query']) && !empty($params['query']) ? [
                    [
                        'multi_match' => [
                            'query' => $params['query'],
                            'fields' => [
                                'name',
                                'name.ngram'
                            ],
                            'analyzer' => 'ngram_index_analyzer',
                            'operator' => 'and',
                        ],
                    ],
                    [
                        'match' => [
                            'product_no' => [
                                'query' => $params['query'],
                                'boost' => 50
                            ]
                        ]
                    ],
                    [
                        'nested' => [
                            'path' => 'vendors',
                            'query' => [
                                'bool' => [
                                    'must' => [
                                        'term' => [
                                            'vendors.vendor_sku' => [
                                                'value' => $params['query'],
                                                'boost' => 30
                                            ]
                                        ]
                                    ]
                                ]
                            ]
                        ]
                    ],
                ] : false)),

                'filter' => array_values(array_filter([
                    @ $params['marketplace_id'] ? ['term' => ['marketplace_id' => $params['marketplace_id']]] : false,
                    [
                        'nested' =>
                            [
                                'path' => 'vendors',
                                'query' => [
                                    'bool' => [
                                        'must' => array_values(array_filter([
                                            [
                                                'terms' => [
                                                    'vendors.vendor_id' => $params['allowed_vendor_ids']
                                                ]
                                            ],
                                       
                                        ]))
                                    ]
                                ]
                            ]
                    ]
                ])),
            ]),
        ]
    ]
];

With the help of filters I want to add a restriction for the selection.
There is a buyer in the system, he has access to a certain list of vendors and a marketplace, so the buyer can only buy from certain vendors. Using the filter and the expression in it - (vendors.vendor_id' => $params['allowed_vendor_ids']) I'm trying to limit the selection of products that are associated with available vendors.

Everything works fine as long as the search string in multi_match matches any available product, but as soon as it does not match, products that have nothing to do with the selection criterion are returned. As I understand it, elastic does not find it using multi_match and therefore returns the first 10 products by vendor filter, although I need an empty result. That is, 10 products are returned that have the id of the transferred vendors. I need the behavior of not OR but AND, so that the filter does not additionally output something, but specifies the selection, and if multi_match did not find anything, then an empty result was returned.
Please tell me what needs to be changed?

normal behavior

random result

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.