dengliming/redis-modules-java

search failed with cluster

chenlizhao opened this issue · 11 comments

centos7.9, redis-6.2.5, I create a cluster with 6 nodes, and json set one document as:

RediSearchClient rediSearchClient = new RediSearchClient(config);
RediSearch rediSearch = rediSearchClient.getRediSearch("testSearch");
rediSearch.dropIndex();
rediSearch.createIndex(new io.github.dengliming.redismodule.redisearch.index.schema.Schema()
.addField(new io.github.dengliming.redismodule.redisearch.index.schema.TextField("title"))
.addField(new io.github.dengliming.redismodule.redisearch.index.schema.TextField("content"))
.addField(new Field("age", FieldType.NUMERIC))
.addField(new Field("location", FieldType.GEO)));
Map<String, Object> fields = new HashMap<>();
fields.put("title", "Hi");
fields.put("content", "OOOO");
RedisJSONClient redisJSONClient = new RedisJSONClient(config);
RedisJSON redisJSON = redisJSONClient.getRedisJSON();
redisJSON.set("user1", SetArgs.Builder.create(".", GsonUtils.toJson(fields)));

and search without filter as:
SearchResult searchResult = rediSearch.search("*", new SearchOptions()
.noStopwords()
.language(RSLanguage.ENGLISH));

but the result is:
{
total: 0,
documents: [ ]
}

what's wrong with my search?

Currently. we don't support indexing JSON documents yet. see #26

@chenlizhao Can you try this?

public void testIndexOnJSON() {
RediSearch rediSearch = getRediSearchClient().getRediSearch("userIdx");
assertThat(rediSearch.createIndex(
new Schema()
.addField(new TextField("$.user.name").attribute("name"))
.addField(new TagField("$.user.tag").attribute("country")),
new IndexOptions()
.definition(new IndexDefinition(IndexDefinition.DataType.JSON)))).isTrue();
RedisJSON redisJSON = getRedisJSONClient().getRedisJSON();
redisJSON.set("myDoc", SetArgs.Builder.create("$", "{\"user\":{\"name\":\"John Smith\","
+ "\"tag\":\"foo,bar\",\"hp\":1000, \"dmg\":150}}"));
SearchResult result = rediSearch.search("@name:(John)", new SearchOptions());
assertThat(result.getTotal()).isEqualTo(1);
assertThat(result.getDocuments().get(0).getId()).isEqualTo("myDoc");
}

@chenlizhao Can you try this?

public void testIndexOnJSON() {
RediSearch rediSearch = getRediSearchClient().getRediSearch("userIdx");
assertThat(rediSearch.createIndex(
new Schema()
.addField(new TextField("$.user.name").attribute("name"))
.addField(new TagField("$.user.tag").attribute("country")),
new IndexOptions()
.definition(new IndexDefinition(IndexDefinition.DataType.JSON)))).isTrue();
RedisJSON redisJSON = getRedisJSONClient().getRedisJSON();
redisJSON.set("myDoc", SetArgs.Builder.create("$", "{\"user\":{\"name\":\"John Smith\","
+ "\"tag\":\"foo,bar\",\"hp\":1000, \"dmg\":150}}"));
SearchResult result = rediSearch.search("@name:(John)", new SearchOptions());
assertThat(result.getTotal()).isEqualTo(1);
assertThat(result.getDocuments().get(0).getId()).isEqualTo("myDoc");
}

Yes, the search is ok for single node now, but for cluster, the search is still fail, for example, json of user john is set on node1, but the schema is created on node2, when I search user john, the result is still empty.

@chenlizhao Can you provide the code of your example?

@dengliming here is my code:

Config config = new Config();
config.useClusterServers().addNodeAddress("redis://10.200.5.119:7001", "redis://10.200.5.119:7002", "redis://10.200.5.119:7003",
"redis://10.200.5.119:7004", "redis://10.200.5.119:7005", "redis://10.200.5.119:7006");
RediSearchClient rediSearchClient = new RediSearchClient(config);
RediSearch rediSearch = rediSearchClient.getRediSearch("userIdx");
rediSearch.dropIndex();
rediSearch.createIndex(new io.github.dengliming.redismodule.redisearch.index.schema.Schema()
.addField(new io.github.dengliming.redismodule.redisearch.index.schema.TextField("$.title").attribute("title"))
.addField(new io.github.dengliming.redismodule.redisearch.index.schema.TextField("$.content").attribute("content"))
.addField(new Field("$.age", FieldType.NUMERIC))
.addField(new Field("$.location", FieldType.GEO)),
new IndexOptions().definition(new io.github.dengliming.redismodule.redisearch.index.IndexDefinition(io.github.dengliming.redismodule.redisearch.index.IndexDefinition.DataType.JSON)));
Map<String, Object> fields = new HashMap<>();
fields.put("title", "Hi");
fields.put("content", "OOOO");
fields.put("age", 2);
RedisJSONClient redisJSONClient = new RedisJSONClient(config);
RedisJSON redisJSON = redisJSONClient.getRedisJSON();
redisJSON.set("user1", SetArgs.Builder.create("$", GsonUtils.toJson(fields)));
fields.put("title", "test");
redisJSON.set("user2", SetArgs.Builder.create("$", GsonUtils.toJson(fields)));
io.github.dengliming.redismodule.redisearch.search.SearchResult searchResult = rediSearch.search("*", new SearchOptions()
.noStopwords()
.language(RSLanguage.ENGLISH));

It should returns both user1 and user2, but user2 is not set on the same node of user1, so the result only returns use1

Hey. how did you build/run the module?
see RediSearch/RediSearch#2557

when I enabled COORD=oss, the search result contains duplicated keys, what should I do?

@chenlizhao Did you flushdb and retry again? Then paste your results here.

I clean all db and recreate cluster, but the result is still not ok as:

{
total: 3,
documents: [
{
id: "user1",
score: 1,
fields: {
$: "{"title":"Hi","content":"OOOO","age":2}"
}
},
{
id: "user2",
score: 1,
fields: {
$: "{"title":"test","content":"OOOO","age":2}"
}
},
{
id: "user2",
score: 1,
fields: {
$: "{"title":"test","content":"OOOO","age":2}"
}
}
]
}

there are two user2 in result.

127.0.0.1:7005> FT.SEARCH userIdx *

  1. (integer) 3
  2. "user1"
    1. "$"
    2. "{"title":"Hi","content":"OOOO","age":2}"
  3. "user2"
    1. "$"
    2. "{"title":"test","content":"OOOO","age":2}"
  4. "user2"
    1. "$"
    2. "{"title":"test","content":"OOOO","age":2}"

@chenlizhao Hey, May I ask why you closed this issue? have you solved your problem?

@dengliming yes, after I updated to latest version of redisearch, it was ok, thx for your help!