Azure Search - Match value from comma-separated values string - azure

How do you structure a Azure POST REST call to match a value on a comma-separated list string?
For Example:
I want to search for "GWLAS" or "SAMGV" within the Azure field "ProductCategory".
The "ProductCategory" field in the documents will have a comma-separated value string such as "GWLAS, EXDEB, SAMGV, AMLKYC".
Any ideas?

If you use the default analyzer for your ProductCategory field (assuming it is searchable), it should word-break on commas by default. This means all you should need to do is search for the terms you're interested in and limit it to the right field:
POST /indexes/yourindex/docs/search?api-version=2016-09-01
{
"search": "GWLAS SAMGV",
"searchFields": [ "ProductCategory" ]
}
There are other ways to do this, but this is the simplest. If you already scope parts of your search query to other fields, here is how you can scope just the desired terms to ProductCategory:
POST /indexes/yourindex/docs/search?api-version=2016-09-01
{
"search": "(Name:\"Anderson John\"~3 OR Text:\"Anderson John\"~3) AND ProductCategory:GWLAS SAMGV",
"queryType": "full"
}
Please consult the Azure Search REST API documentation for details on other options you can set in the Search request. Also, this article will help you understand how Azure Search executes queries. You can find the reference for the full Lucene query syntax here.

Related

How to disable tokenization for Azure Search Autocomplete?

I've created Azure Search Suggester for "full_name" index field in order to support autocomplete functionality. Now when I use Azure autocomplete REST endpoint by using "search" parameter as a let's say "Lor" I only get back the result "Lorem" not the "Lorem Ipsum". Is there any way to disable tokenization for suggester and to get back full name like "Lorem Ipsum" for the search term "Lor" for autocomplete?
The Autocomplete API is meant to suggest search terms based on incomplete terms one is typing into to the search box (type-ahead). It supports three modes:
oneTerm – Only one term is suggested. If the query has two terms, only
the last term is completed. For example:
"washington medic" -> "medicaid", "medicare", "medicine"
twoTerms – Matching two-term phrases in the index will be suggested,
for example:
"medic" -> "medicare coverage", "medical assistant"
oneTermWithContext – Completes the last term in a query with two or
more terms, where the last two terms are a phrase that exists in the
index, for example:
"washington medic" -> "washington medicaid", "washington medical"
The twoTerms mode might work for you. If you're looking for an API that suggests documents based on an incomplete query term, try the Suggestions API. It returns the entire contents of a field that has a Suggester enabled for all documents that matched the query.

Azure Search Lucene Query Incorrect Result

I am currently using Azure Search to bring back images stored in blob storage, based off filters that are passed in by the user. Below is my Azure Search, which I thought should filter all of the content specified in the tags field as a AND:
search=foreignId:d0c41422-acfa-4e4b-a9db-8c06b6860f3f, tags:SiteRef +\""TY0033"\" + BlockRef + \""00"\" + Disipline + \""FABRIC"\"&searchMode=all&queryType=full
and what it brings back (which is wrong as you can see from the BlockRef, though if I pass CN0001, it brings the correct values):
"foreignId": "d0c41422-acfa-4e4b-a9db-8c06b6860f3f",
"description": "Health & Safety Eire - Site Photo - TY0033-01-
FABRIC-005",
"fileName": "TY0033-01-FABRIC-005",
"fileExtension": ".jpg",
"createdAt": "26/11/2018 02:00:24",
"tags": "[{\"TagName\":\"SiteRef\",\"Value\":\"TY0033\"},{\"TagName\":\"BlockRef\",\"Value\":\"01\"},{\"TagName\":\"Disipline\",\"Value\":\"FABRIC\"},{\"TagName\":\"PhotoNumber\",\"Value\":\"005\"}]",
"longitude": 0,
"latitude": 0
95% of the time this is working perfectly, however the other 5% of the time, the images comes back incorrect, as Azure search has given the incorrect details.
I have checked and it seems to be because it is not respecting the multiplicity of the search terms. I am new to Azure Search, so I am wondering if I am doing it correctly?
Any help would be greatly appreciated
Index Definition:
Index Definition
Edit: Updated Post with index definition
In your query you check if foreignId is equal to d0c41422-acfa-4e4b-a9db-8c06b6860f3f and tags field contains SiteRef and if any searchable field contains TY0033, BlockRef, 00, Disipline and FABRIC. In your case all fields are searchable. Thus:
forignId matches
tags contains SiteRef
TY0033, BlockRef, Disipline and FABRIC are in tags field
00 is in createdAt field, as standard Lucene analyzer tokenizes "26/11/2018 02:00:24" into 26,11,2018,02,00,24
In order to search in tags field you should rewrite your query as follows:
search=foreignId:d0c41422-acfa-4e4b-a9db-8c06b6860f3f AND tags:(SiteRef AND \""TY0033"\" AND BlockRef AND \""00"\" AND Disipline AND \""FABRIC"\")&searchMode=all&queryType=full
It might be worthwhile to use proximity search to make sure you correlate occurrences field/value pairs, e.g.: BlockRef and 00 e.g., "BlockRef 00"~1

How can I use AzureSearch with wildcard

I want to search for a field that has the name "14009-00080300", and I want to get a hit when searching only on a part of that, for example "14009-000803".
Using this code I dont get any hits:
{
"search": "\"14009-000803\"*",
"count":true,
"top":10
}
Is there a way to use azure search like SQL uses its wildcard search? (select * from table where col like '%abc%' ?
You can get your desired result by performing a full query with Lucene syntax (as noted by Sumanth BM). The trick is to do a regex search. Modify your query params like so:
{
"queryType": "full",
"search": "/.*searchterm.*/",
"count":true,
"top":10
}
Replace 'searchterm' with what you are looking for and azure search should return all matches from your index searchable columns.
See Doc section: MS Docs on Lucene regular expression search
You can use generally recognized syntax for multiple () or single (?) character wildcard searches. Note the Lucene query parser supports the use of these symbols with a single term, and not a phrase.
For example to find documents containing the words with the prefix "note", such as "notebook" or "notepad", specify "note".
Note
You cannot use a * or ? symbol as the first character of a search.
No text analysis is performed on wildcard search queries. At query time, wildcard query terms are compared against analyzed terms in the search index and expanded.
SearchMode parameter considerations
The impact of searchMode on queries, as described in Simple query syntax in Azure Search, applies equally to the Lucene query syntax. Namely, searchMode in conjunction with NOT operators can result in query outcomes that might seem unusual if you aren't clear on the implications of how you set the parameter. If you retain the default, searchMode=any, and use a NOT operator, the operation is computed as an OR action, such that "New York" NOT "Seattle" returns all cities that are not Seattle.
https://learn.microsoft.com/en-us/rest/api/searchservice/simple-query-syntax-in-azure-search
Reference: https://learn.microsoft.com/en-us/rest/api/searchservice/lucene-query-syntax-in-azure-search#bkmk_wildcard

Personalized search in Azure Search

I am looking at Azure Search for a message service. Very simplified, we have an Azure App Service (running .NET) and two tables on SQL Azure:
Message: Id, Subject, Body, [...]
MessageRecipient: Id, MessageId, UserId, [...]
One message has 1:N recipients.
I want an index to search the Subject and Body of Message, but the results must be filtered on the current user being a recipient of the message. I can't seem to find a good way to implement this so it scales well to high volumes. Returning all search results from the index and then filtering on UserId in my application would generate a lot of unnecessary overhead. And indexing each message duplicated for each UserId is even worse.
How would you best implement a recipient-filtered message search?
Thanks,
TGM
In similar situations I have utilized the Collection(Edm.String) data type in my search index. So an example document from your index would look something like this:
{
messageId : 1,
subject : "Why Azure Search is cool",
body: "Just because",
recipientIds : ["123", "456", "789"]
}
The recipientIds field is defined as type Collection(Edm.String) in the index schema.
Then you can use the "any" and "all" OData expressions to filter your searches. So, if you wanted to find messages sent to recipient id 123 your filter expression would look like this:
$filter=recipientIds/any(r: r eq '123')
See the Azure Search OData expression docs for more details.

Can I "Exact Search" for targeted field(s) and Search across other fields as well?

The "Exact Search" fields use their own custom analyzer, while the Search fields use a language specific custom analyzer (built on MicrosoftStemmingTokenizerLanguage.French, for example).
I can't seem to use $filter for the "Exact Search" field, because $filter considers the entire field, and doesn't use the custom analyzer of the field.
Azure Search docs indicate this about field scoped queries.
"You can specify a fieldname:searchterm construction to define a fielded query operation, where the field is a single word, and the search term is also a single word"
There is no clear way on how to do this in Azure. We know we can use the searchFields parameter in our Azure Search Rest API calls to target specific fields, but how do we search ALL fields for 1 term while specifically searching some fields for specific terms, basically doing an “AND” between them?
This is possible using the Lucene query syntax.
Construct your query like this, where "chair" is the term to search for in all fields, and field1 and field2 are fields where you want to search for specific terms:
chair AND field1:something AND field2:else
In terms of how you use this in the REST API, just embed it in your search parameter. If you're using GET it looks like this (imagine it URL-encoded):
search=chair AND field1:something AND field2:else
If you're using POST, it goes in the request body and looks like this:
{
"search": "chair AND field1:something AND field2:else",
... (other parameters)
}

Resources