Hi:
I have two documents:
title body
Lucene In Action A high-performance, full-featured text search engine library.
Lucene Practice Use lucene in your application
Now,I search "lucene performance" using
private String[] f = { "title", "body"};
private Occur[] should = { Occur.SHOULD, Occur.SHOULD};
Query q = MultiFieldQueryParser.parse(Version.LUCENE_29, "lucene performance", f, should,new IKAnalyzer());
Then I get two hits:
"Lucene In Action" and "Lucene Practice".
However I do not want the "Lucene practice" in the search result.
That's to say,I just want the documents who own all my search terms can be returned,the "lucene parctice" does not contain the term "performance",so it should not be returned.
Any ideas?
Lucene cannot match across fields. That is to say, for the query "a b", it won't match "a" in title and "b" in body. For that you need to create another field, say, all_text, which has title and body both indexed.
Also, when you are searching for "lucene performance" I suppose you are looking for documents that have both the terms - lucene as well as performance. By default, the boolean operator is OR. You need to specify default operator as AND to match all the terms in the query. (Otherwise in this case, the query "lucene performance" will start returning matches that talk about database performance.)
Related
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
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)
}
I'm using solr for an enterprise application. So far it works well, as I am using a ngram field to search against. It works correctly for partial queries (match against indexed ngrams). But the problem I have is, how to enforce exact query matches?. For an example the query "Test 1" should match exactly the same text as it is when the user enter it with double quotation marks. Currently Since I have used some tokenizers and filters, the double quotation marks get filtered out, there's no difference in the queries "test 1", "tEst 1" or "TEST 1" (that is because of the analyzer chain I use, but it is needed to work with ngrams and partial search).
Currently I'm searching against a ngram query field. In order to enforce exact query match, what should I do? what is the best practice?. currently what I think is to identify the double quotation marks from client side and change the query field to the original field (with out ngrams). But I feel like there should be a better way of doing this, since the problem I have is generic and solr is a complete enterprise level search engine.
You can have another field for it and add string as the fieldType for the same and index it with same.
When you want to perform the exact match you can query on the above field.
And when you want to perform partial search ..you can query to the earlier field which is indexed by ngram.
OR.. Here is another way you can try.
You have defined the current field type using the ngram. In that while indexing you can define the ngram tokenizer and for the query you mention keywordTokenizer and lowercase filter factory only.
While indexing the text will be tokenized and while performing the query it will not.
Problem:
I have a movie information in solr. Two string fields define the movie title and director name. A copy field define another field which solr search for default.
I would like to have google like search with limited scope as follows. How to achieve it.
1)How to search solr for contains
E.g.
a) If the movie director name is "John Cream", searching for joh won't return anything. However, searchign for John return the correct result.
b) If there is a movie title called aaabbb and another one called aaa, searching for aaa returns only one result. I need to return the both results.
2) How to account for misspelling
E.g.
If the movie director name is "John Cream", searching for Jon returns no results. Is there a good sounds like (soundex) implementation for solr. If so how to enable it?
You can use solr query syntax
Searching for contains is obviously possible using wildcards (eg: title:*aaa* will match 'aaabbb' and also 'cccaaabbb'), but be careful about it, becouse it doesn't use indexes efficently. Do you really need this?
A soundex like search is possible applying solr.PhoneticFilterFactory filter to both your index and query. To achieve this define your fieldType like this in schema:
<fieldType name="text_soundex" class="solr.TextField">
...
<filter class="solr.PhoneticFilterFactory" encoder="Soundex" inject="true"/>
</fieldType>
If you define your "director" field as "text_soundex" you'll be able to search for "Jon" and find "John"
See http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters for more information.
Things you are asking, the first one is definitely achievable from Solr. I don't know about soundex.
1)How to search solr for contains
You can store data into string type of field or text type of field. In string field by wild card searching you can achieve the result (E.g field1:"John*"). Also you should look into different types of analyzers. But before everything, please look into the Solr reference http://wiki.apache.org/solr/.
def self.get_search_deals(search_q, per = 50)
data = Sunspot.search(Deal) do
fulltext '*'+search_q +'*', fields: :title
paginate page: page_no, per_page: per
end
data.results
end
searchable do
text :title
end
just pass string as "*sam*"
Is it possible to search solr attribute fields (non solr.TextField types) using a substring/wildcard/partial string match?
For instance if I have a solr.StrField field and documents that contain the string "1234567890" I want to be able to search on "456" and have that document returned.
From what I can see only textfields can be searched in this method using things like EdgeNGram and the like, but not attribute fields??
You can have the partial matches working for String as well Text fields for wildcards.
If the query parsers you are using, supports leading wildcard queries, you can easily search for *456*, and this should match 1234567890.
However, EdgeNGram would only work for solr.TextField, as solr.strField do not allow analysers to be added to it.
So you can only define fields with class as solr.TextField and have the EdgeNGram in the analysis chain, which would break down the indexed terms into shingles for partial matching.