Sphinx search infix and exact words in different fields - full-text-search

I'm using sphinx as search engine and I need to be able to do a search in different fields but using infix for one of the fields and exact word matches for another.
Simple example:
My source has for field_1 the value "abcdef" and for field_2 the value "12345", what I need to accomplish is to be able to search by infix in field_1 and exact word in field_2. So a search like "cde 12345" would return the doc I mentioned.
Before when using sphinx v2.0.4 I was able to obtain these results just by defining infix_fields/prefix_fields on my index but now that I'm using v2.2.9 with the new dict=keywords mode and infix_fields are deprecated.
My index definition:
index my_index : my_base_index
{
source = my_src
path = /path/to/my_index
min_word_len = 1
min_infix_len = 3
}
I've tried so far to use extended query syntax in the following way:
$cl = new SphinxClient();
$q = (#(field_1) *cde* *12345*) | (#(field_2) cde 12345)
$result = $cl->Query($q, 'my_index');
This doesn't work because for each field, sphinx is doing an AND search and one of the words is not in the specified field, "12345" is not a match on field_1 and "cde" is not a match in field_2. Also I don't want to do an OR search, but need the both words to match.
Is there a way to accomplish what I need?

Its a bit tricky, but can do
$q = "((#field_1 *cde*) | (#field_2 cde)) ((#field_1 *12345*) | (#field_2 12345))"
(dont need the brackets around the field name in the #syntax - if just one field, so removed them for brevity)

Related

How to properly perform like queries with Quickbase

I am working with quicktable queries and everything seems to be fine.
Now I want to perform queries using like operators. For instance in PHP I can do something like:
$data ='content to search';
$stmt = $db->prepare('SELECT * FROM members where name like :name OR email like :email limit 20');
$stmt->execute(array(
':name' => '%'.$data.'%',
':email' => '%'.$data.'%',
));
Now in quick table, I have tried using CT, EX or HAS parameter etc with OR Operators. Only CT gives nearby result but not exact as per code below.
//Email = 7
//name =8
{
"from": "tableId",
"where": "{7.CT.'nancy#gmail.com'}OR{8.CT.'nancy'}"
}
Is there any way I can obtain a better search with like operators with Quickbase. The documentation here does not cover that.
CT is the closest string comparison operator in Quick Base to LIKE in SQL, but since you can't use wildcards in Quick Base queries you might need to group multiple query strings to achieve the same result. The is also a SW operator that can sometimes come in helpful for comparing parts of a strings.

How to search records with a string which contains some characters of the target field string in Odoo v10?

I am using Odoo v10. While scanning a barcode, a string contains some characters of a char field value. For example,
A field value ('tracknum') = "20171103"
Search the field by entering a string "xxxxxx20171103" or "xxxx20171103yyy"
is there any way to do it?
I have modified the search view :
<field name="tracknum" string="Tracknum" filter_domain="..."/>
How to dig out related records?
You can create an auxiliar computed field like this
custom_name = fields.Char(
string='Custom',
compute='_compute_custom_name',
search='_search_custom_name'
)
#api.multi
#api.depends()
def _compute_custom_name(self):
''' The field has to be a computed field
You do not need to do anything here
'''
pass
def _search_custom_name(self, operator, value):
''' Actually this converts a domain into another one.
With this new domain Odoo can search well
Arguments:
* operator: if you are searchig words it is going to be ilike
* value: the string ro search
The method could return something like this
* [('id', 'in', id_list)]
'''
all_records = self.search([]) # recordset with all the values of the current model
ids = []
if operator == 'ilike':
ids = all_records.filtered(lambda r: r.tracknum in value).mapped('id')
return [('id', 'in', ids)]
Then you can add this field to the search view like this:
<field name="custom_name" string="Tracking Number" />
Keep in mind that it is not a stored field, so it is going to be very inefficient. And you should iterate over all the values each time you want to make a search.
Once you have added the field to the search view it shoul look like this, Tracking Number should appear in the field name

CloudSearch or CloudQuery to search by 'contains' in CloudBoost

I need to filter data by substring, I mean, if I have got this data:
'John','Markus','james'
And i want to look by all elements which contains 'm' it should return:
'Markus','james'
Or if I filter by 'hn', the results should be:
'John'
How can I do it using CloudSearch or CloudQuery?
EDIT: I have seen wildcard method which seems to fit with my requirements, except for only is allowed a column (string) param. I would need to filter also by columns (array). As in searchOn method.
This should work I think. did you try it with this :
var query = new CB.CloudQuery('TableName');
//then you can:
query.substring('ColName','Text');
//or
query.substring(['ColName1','ColName2'],'Text');
//or
query.substring('ColName',['Text1', 'Text2']);
//or
query.substring(['ColName1','ColName2'],['Text1', 'Text2']);
query.find(callback);

multiple where statements combined with OR in Activerecord and Ruby

I would like to do a query with activerecord (not rails) with multiple keywords that are contained in a field (so I have to use LIKE) but I don't know in advance how many keywords there will be.
My query looks like this, Word is my model.
query = ['word1','word2'] #could be more
puts "searching for #{query}"
qwords = Word.none
query.each do |qword|
puts qwords.where("word like ?", "%#{qword}%").to_sql
qwords = qwords.where("word like ?", "%#{qword}%")
end
Which gives nothing because the queries are added as AND but I need OR.
searching for ["word1", "word2"]
SELECT "words".* FROM "words" WHERE (word like '%word1%')
SELECT "words".* FROM "words" WHERE (word like '%word1%') AND (word like '%word2%')
#<ActiveRecord::Relation []>
I can't use Word.where(word: query) which uses the sql IN keyword because that only works for exact matches.
Is there a solution that doesn't involves concatenating the whole SQL that is needed ?
query = "word1 word2" #could be more
puts "searching for #{query}"
query_length = query.split.length #calculates number of words in query
Now you can put together the number of SQL queries you need regardless of the number of keywords in your query
Word.where([(['word LIKE ?'] * query_length).join(' OR ')] + (query.split.map {|query| "%#{query}%"}))
This should return
["word LIKE ? OR word LIKE ?", "%word1%", "%word2%"]
for your SQL search
Had forgotten about this question and found a solution myself afterward.
I now do the following. The problem was caused by using the resultset to do my next query on while like this it is on the whole recordset and the results are added.
#qwords = Word.none
$query.each do |qword|
#qwords += Word.where(word: qword)
end

Substring with spacebar search in RavenDB

I'm using such a query:
var query = "*" + QueryParser.Escape(input) + "*";
session.Query<User, UsersByEmailAndName>().Where(x => x.Email.In(query) || x.DisplayName.In(query));
With the support of a simple index:
public UsersByEmailAndName()
{
Map = users => from user in users
select new
{
user.Email,
user.DisplayName,
};
}
Here I've read that:
"By default, RavenDB uses a custom analyzer called
LowerCaseKeywordAnalyzer for all content. (...) The default values for
each field are FieldStorage.No in Stores and FieldIndexing.Default in
Indexes."
The index contains fields:
DisplayName - "jarek waliszko" and Email - "my_email#domain.com"
And finally the thing is:
If the query is something like *_email#* or *ali* the result is fine. But while I use spacebar inside e.g. *ek wa*, nothing is returned. Why and how to fix it ?
Btw: I'm using RavenDB - Build #960
Change the Index option for the fields you want to search on to be Analyzed, instead of Default
Also, take a look here:
http://ayende.com/blog/152833/orders-search-in-ravendb
Lucene’s query parser interprets the space in the search term as a break in the actual query, and doesn’t include it in the search.
Any part of the search term that appears after the space is also disregarded.
So you should escape space character by prepending the backslash character before whitespace character.
Try to query *jarek\ waliszko*.
So.., I've came up with an idea how to do it. I don't know if this is the "right way" but it works for me.
query changes to:
var query = string.Format("*{0}*", Regex.Replace(QueryParser.Escape(input), #"\s+", "-"));
index changes to:
public UsersByEmailAndName()
{
Map = users => from user in users
select new
{
user.Email,
DisplayName = user.DisplayName.Replace(" ", "-"),
};
}
I've just changed whitespaces into dashes for the user input text and spacebars to dashes in the indexed display name. The query gives expected results right now. Nothing else really changed, I'm still using LowerCaseKeywordAnalyzer as before.

Resources