I use multiple indexes on a single Redisearch, and each index is associated with a class in the code.
For example, the data of XYZ ( List<XYZ> ) is saved via an index XYZ, whereas the data of ABC (List<ABC>)via ABC.
The problem is, when I search for data of XYZ using the index XYZ, data of ABC also shows up in the search.
This can be easily recreated like this:
//declare three indexes. Some of them contain duplicate field names but this is to be expected (in real life we would have things like timestamps that spread across indexes)
ft.create sample1 schema sampletext text
ft.create sample2 schema sampleinteger numeric sortable
ft.create sample3 schema sampletext text sampleinteger numeric
//then we add a text under sample1
ft.add sample1 sample1doc 1.0 fields sampletext "hello this document is under an index called sample1"
//then display all the documents associated with the index sample3
ft.search "sample3" "*"
//-> prints the document above "hello this document is under..."
//display all the documents associated with the index sample2
ft.search "sample2" "*"
//-> the same result
Why is this? Is there any good workaround for this?
I know FT.ADD is deprecated now but the C# library still internally calls FT.ADD so I need to get it working with FT.ADD, plus the document we just added only contains "sampletext" so it still shouldn't appear under sample2 anyway.
RediSearch 2.0 indexes hashes in the background as they are loaded via an HSET command. Even the FT.ADD command, which, as you stated, was deprecated, checks the input and translates it into an HSET command.
When creating an index using FT.CREATE, you can specify either a prefix for your document or use a filter.
If possible, you should use a prefix as it is more performant, and your command will look something like -
ft.create sample1 prefix 1 txt: schema sampletext text
ft.create sample2 prefix 1 num: schema sampleinteger numeric sortable
hset txt:sample1doc sampletext "hello this document is under an index called sample1"
You will receive -
ft.search sample1 *
1) (integer) 1
2) "txt:sample1doc"
3) 1) "sampletext"
2) "hello this document is under an index called sample1"
ft.search sample2 *
1) (integer) 0
Cheers
Related
I am using Redisearch module in Redis and trying to search for a value in TEXT field using below query. It returns all the documents with lower case values like 'test or Test' and no data which has all the upper case letters 'TEST' are being returned.
FT.search MyIndex #MyField:"test"
Kindly suggest something. Thank you.
I have a similar Index as created below, I get all the records only when I add 'tjøp | TJØP' or 'tjøp*' in the query.
FT.CREATE MyIndex SCHEMA name TEXT
ft.add MyIndex "110011" 1.0 FIELDS name "tjøp plane"
ft.add MyIndex "110012" 1.0 FIELDS name "file TJØP"
ft.add MyIndex "110013" 1.0 FIELDS name "one TJØP more"
ft.add MyIndex "110015" 1.0 FIELDS name "one TJØP a/s more"
127.0.0.1:6379> ft.search MyIndex #name:"tjøp"
(integer) 1
"110011"
"name"
"tj\xc3\xb8p plane"
127.0.0.1:6379> ft.search MyIndex #name:"tjøp | TJØP"
(integer) 4
"110011"
"name"
"tj\xc3\xb8p plane"
"110015"
"name"
"one TJ\xc3\x98P a/s more"
"110013"
"name"
"one TJ\xc3\x98P more"
"110012"
"name"
"file TJ\xc3\x98P"
I have a key which has fields and values. All the fields have string values.
One of these fields I want it to be a table or set or list (meaning holding multiple values). This field is called zonetable
I only know how to use hset but as far as I know it cannot do what I want. I would like to do something like that
hmset L0001:ad65ed38-66b0-46b4-955c-9ff4304e5c1a field1 blabla field2 blibli zonetable [1,2,3,4]
Key : L0001:ad65ed38-66b0-46b4-955c-9ff4304e5c1a
field1: "string value"
field2: "string value"
zonetable: [1,2,3,4] ---- the table
Maybe you can make use of Json. use json serialize your table (list or something) into a json string, then use hset to save it into your redis.
When you want to retrieve it, first get it from redis and then deserialize it from json to list.
If you use python, you can do it like this:
table = json.dumps(zonetable)
redis.hset(Key, 'zonetable', table)
when you want to retrieve it :
table = redis.hget(Key, 'zonetable')
zonetable = json.loads(table)
As you say, you use the native command, you can also do this.
first, convert your zonetable to json string using python interpreter
>>> import json
>>> table = [1,2,3,4]
>>> json.dumps(table)
'[1, 2, 3, 4]'
then use this in redis-cli
hmset L0001:ad65ed38-66b0-46b4-955c-9ff4304e5c1a field1 blabla field2 blibli zonetable '[1,2,3,4]'
Yes, one more thing I want to say, if you know the rule of how to convert object to json, you could do it by yourself.
TABLES: VBRK.
DATA: BEGIN OF it_test,
BUKRS LIKE VBRK-BUKRS,
FKDAT LIKE VBRK-FKDAT,
END OF it_test.
DATA: wa_test LIKE it_test.
SELECT * FROM VBRK INTO CORRESPONDING FIELD OF wa_test.
IF wa_test-BUKRS = 'xxxx'.
wa_test-BUKRS = 'XXXXX' "Problem occurs here as the BUKRS allow 4 value
APPEND wa_test TO it_test.
ENDIF.
Then I want to map the internal table to output as ALV table. Is they any way to change the field length afterwards?
Apart from multiple issues in your code, you can't. If you need something similar to that, add an additional field to the structure with whatever size you require and copy the values over.
If the objective is to output something to the screen that is different(or differently formatted) that what is stored internally(or in the database), then the use of a data element with a conversion exit maybe the way to go.
For an example, look at the key fields of table PRPS.
Expanding the answer of vwegert:
The MOVE-CORRESPONDINGcommand (and SELECT ... INTO CORRESPONDING FIELDS) don't need the same field type. The content is converted. So you could define a 5-character field in your internal structure and copy the BUKRS-value into this 5-character field:
TABLES: VBRK.
DATA: BEGIN OF it_test,
BUKRS(5), "longer version of VBRK-BUKRS,
FKDAT LIKE VBRK-FKDAT,
END OF it_test.
DATA: tt_test TYPE STANDARD TABLE OF it_test.
* I would strongly recommend to set a filter!
SELECT * FROM VBRK INTO CORRESPONDING FIELD OF it_test.
IF it_test-BUKRS = 'xxxx'.
it_test-BUKRS = 'XXXXX'.
APPEND it_test to tt_test.
ENDIF.
ENDSELECT.
A pitfall: When you use it with ALV you will loose the field description. (on the other side, the field description of the original field will not fit any longer the new field.)
I have an SQL query problem in my Starcounter database where I want to write a query that retrieves html pages (Content) containing a specific set of keywords based on the following models.
class Keyword {
int Id;
string Text;
}
Example data:
Id Text
1 google
2 advertising
3 twitter
class Content {
int Id;
string Text;
}
Example data:
Id Text
4 "google advertising is nice for marketers"
5 "twitter is not a good way to get exposure"
class HasWord : Relation {
Keyword Keyword;
Content Content;
}
Example data:
Keyword Content
1 4
2 4
3 5
How would I write a Query that retrieves all Content containing 2 specific words, in this case "google" and "advertising"? Is it possible without nested queries?
Input:
"google" & "advertising"
Desired output:
"google advertising is nice for marketers"
If you need to find an instance of Content , which Text contains both words, then you can use operator LIKE with regular expression, which is described here. For example:
SELECT Text
FROM Content
WHERE Text LIKE '%google%' AND Text LIKE '%advertising%'
If you need to find an instance of Content, which is in relationship with both keywords, then you can use self-join. For example
SELECT r1.Content.Text
FROM HasWord r1, HasWord r2
WHERE r1.Content = r2.Content AND
r1.Keyword.Text = 'google' AND r2.Keyword.Text = 'advertising'
Note that the result of the query will contain duplicates.
I have a table(let's call it my_table) with two text fields: title and description. Also I have an index(my_index) that uses next source-query:
SELECT * FROM my_table;
When I need to get all words and frequencies from my_index I use something like:
$indexer my_index --buildstops word_freq.txt 1000 --buildfreqs
But now, I need to get words that are presented only in column title(and their frequencies only from title column). What is the best solution to do this?
Edit:
It will be perfect, if solution won't build new indexes on disk space.
Create a new "index", that only includes the title column. No need to ever build an physical index with it, can just use it with --buildstops :)
Index inheritence, allows its creation with very compact bit in the config file
source my_index_title : my_index {
sql_query = SELECT id,title from my_table
}
index my_index_title : my_index {
source = my_index_title
path = /tmp/my_index_title
}