Search API, how to like query - google-app-engine

I'm using the Search API GAE, how to make a query like "like%"? as is done in SQL example:
select * from person where name like '% john%';

your queryString would be "name: john" on the person index with name field set to be a Text field.
A regular query with ':' or '=' on the Text or HTML type of index value is closest (not same) to 'like' in SQL.
Details on available operators to use in the query are at
https://developers.google.com/appengine/docs/java/search/query_strings#Java_Queries_on_text_and_HTML_fields.
Also check stemming if your use-case is to find words with similar meaning.
https://developers.google.com/appengine/docs/java/search/query_strings#Java_Stemming

Related

Match all documents excluding some terms using full Lucene syntax

Our service's default search web page uses the * full Lucene query to match all documents. This is before the user has provided any search terms. There is some data (test data, in our case) that we want to exclude from the search result.
Is it possible to match all documents but exclude a subset of all documents?
For example, suppose we have an "owners" field and we want to exclude documents with the "testA" and "testB" owner. The following query does not seem to work with the match all approach:
Query: search=* -owners:testA -owners:testB&queryType=full&$orderby=created desc
Error: "Failed to parse query string. See https://aka.ms/azure-search-full-query for supported syntax."
When searching for anything but *, this approach works fine. For example:
Query: search=foo -owners:testA -owners:testB&queryType=full&$orderby=created desc
Result: (many documents matched)
I have considered a $filter for this and using $filter=filterableOwners/all(p: p ne 'testa' and p ne 'testb') but this has the following drawbacks:
the index must be rebuild with a filterable field
analyzers can't be used so case-insensitivity must be implemented by lowercasing the values and filter expression
Ideally this could be done using only the search query parameter with a Lucene query text.
I found a workaround for the issue. If you have a field in your documents that always has a value, you can use a .* regex to match all values in the field and therefore match all documents.
For example, suppose the packageId field has a value for all documents.
Incorrect (as posted in the original question):
Query: search=* -owners:testA -owners:testB&queryType=full&$orderby=created desc
Correct:
Query: search=packageId:/.*/ -owners:testA -owners:testB&queryType=full&$orderby=created desc

Synonym Maps in Azure Search, synonym phrases

I'm trying to use synonym maps in Azure Search and i'm running into a problem. I want to have several words and phrases map into a single search query.
In other words, when i search for either:
product 123, product0123, product 0123
i want the search to return results for a query phrase:
product123.
After reading the tutorial it all seemed pretty straight forward.
I'm using .Net Azure.Search SDK 5.0 so i've done the following:
var synonymMap = new SynonymMap
{
Name = "test-map",
Format = SynonymMapFormat.Solr,
Synonyms = "product 123, product0123, product 0123=>product123\n"
};
_searchClient.SynonymMaps.CreateOrUpdate(synonymMap);
and i use the map on one of the search fields
index.Fields.First(x => x.Name == "Title").SynonymMaps = new[] {"test-map"};
So far so good. Now if i do a search for product0123 i get results for product123 as i would expect. But if i search for a phrase product 123 or product 0123 i get bunch of irrelevant results. It's almost as if the synonym maps do not work with multi word items.
So guess my question is, am i using synonym maps incorrectly or these maps only work with single word synonyms?
Are the phrases, product 123 or product 0123, in double quotes? It is required for the phrases to be in double quotes ("product 123"). Double quotes are the operators for phrase search and in the case for synonyms, they ensure that the terms in the phrase are analyzed and matched against the rules in the synonym map as a phrase. Without it, query parser separates the unquoted phrase to individual terms and tries synonym matching on individual terms. The query becomes product OR 123 in that case.
This documentation explains how queries are parsed (stage 1) and analyzed (stage 2). The application of synonyms in done in the second stage.
To answer your second question in the comment, unfortunately double quotes are required to match multi word synonyms. However, as an application developer, you have the full control of what gets passed to the search service. For example, given a query product 123 from the user, you can re-write the query under the hood to improve precision and recall before it gets passed to the search service. Phrasing or proximity searches can be used to improve precision and wildcard (such as fuzzy or prefix searches) can be used to improve recall of the query. You would rewrite the query product 123 to something like "product 123"~10 product 123 and synonyms will apply to the phrased part of the query.
Nate

Can I do any for loop in Lucene query syntax in Azure search?

In azure search , to search by a word /text in multiple fields at the same time this is how my syntax looks like -
&queryType=full&search=((name:john) || (firstname:john) || (lastname:john) || (middlename:john))
Just wondering if there's any syntax exists like for loop/foreach instead of repeating the search string several times.
imaginary syntax:
&queryType=full&search=(name|| firstname || lastname || middlenamejohn): john
What you're describing is not possible, howerver, in Azure Search your search query is executed against all searchable fields, unless you set the searchFields parameter.
If you want to search over all searchable fields, your query could simply looks like this:
GET https://[service name].search.windows.net/indexes/[index name]/docs?search=john
If the fields in your example are not the only searchable fields and you want you search query to be scoped to them only, use the searchFields parameter:
GET https://[service name].search.windows.net/indexes/[index name]/docs?search=john&searchFields=name,firstname,lastname,middlename
Let me know if that helps

How to create a solr query that searches by multiple keywords in all fields

I want to perform a solr query on all fields for multiple keywords. For example, I want to search for the word "dog" AND the word "cat".
So far, I've tried to do something like this:
q=dog cat
or something like:
q=dog,cat
However, I think my queries are actually doing an OR instead of an AND.
Your question is about the default operator (AND/OR) and you want to search in "all fields".
For most parsers you can use the parameter q.op to change the default parser (e.g. for the Standard Query Parser and the DisMax Query Parser) or you can use the defaultOperator in schema.xml or Schema API.
Be aware that you will search only in the default field.
If you want to search in "all fields" you have to copy all your fields to one field (and use this as default field) or you have to list all your fields in the DisMax qf-parameter.
The results will not be the same: In the second case your "AND"-Search must match one of the fields (with its special tokenizer), in the first each term could be in different fields to match (because in the end all terms are in the default field).

Need help in constructing code for GAE Search Api

I have created Document, added it to Index and used the GAE Search API to search for a text successfully. Please find the sample code below.
search.Document(
fields=[search.TextField(name='id', value=id),
search.TextField(name='search', value=searchT)])
options = search.QueryOptions(returned_fields=['id'])
results = search.Index(name=_D_INDEX_NAME).search(search.Query(searchTxt, options=options))
Now I am unable to understand to to achieve these mentioned below: Some sample code would be really appreciated.
To search for plural variants of an exact query, use the ~ operator:
~"car" # searches for "car" and "cars"
To build queries that reference specific fields, use both field and value in your query, separated by a colon:
field:value
field:"value as a string"
When you add a document, you specify its schema by defining the fields of the document. In your case id and search.
To search for a term that only appears in a specific field you use the notation field:term
search.Index(name=_D_INDEX_NAME).search('search:programming')
For searching plural variants of a term you use the operator ~
search.Index(name=_D_INDEX_NAME).search('~car')
Note however that this won't work in the dev_appserver.

Resources