Skip to content

Commit 7cd4da9

Browse files
committed
fix NLPchina#688 How to use the feature 'inner_hits' when filed is the array of nested object
1 parent 7f8fd69 commit 7cd4da9

File tree

6 files changed

+63
-13
lines changed

6 files changed

+63
-13
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>org.nlpcn</groupId>
55
<artifactId>elasticsearch-sql</artifactId>
6-
<version>6.4.1.0</version>
6+
<version>6.4.1.1</version>
77
<packaging>jar</packaging>
88
<description>Query elasticsearch using SQL</description>
99
<name>elasticsearch-sql</name>

src/main/java/org/nlpcn/es4sql/domain/Condition.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public SQLExpr getValueExpr() {
8484

8585
private boolean isNested;
8686
private String nestedPath;
87+
private String innerHits;
8788

8889
private boolean isChildren;
8990
private String childType;
@@ -114,6 +115,7 @@ public Condition(CONN conn, String name, SQLExpr nameExpr, String oper, Object v
114115

115116
this.isNested = true;
116117
this.nestedPath = nestedType.path;
118+
this.innerHits = nestedType.getInnerHits();
117119
this.isChildren = false;
118120
this.childType = "";
119121
} else if (relationshipType instanceof ChildrenType) {
@@ -229,6 +231,7 @@ public Condition(CONN conn,
229231

230232
this.isNested = true;
231233
this.nestedPath = nestedType.path;
234+
this.innerHits = nestedType.getInnerHits();
232235
this.isChildren = false;
233236
this.childType = "";
234237
} else if (relationshipType instanceof ChildrenType) {
@@ -320,6 +323,14 @@ public void setNestedPath(String nestedPath) {
320323
this.nestedPath = nestedPath;
321324
}
322325

326+
public String getInnerHits() {
327+
return innerHits;
328+
}
329+
330+
public void setInnerHits(String innerHits) {
331+
this.innerHits = innerHits;
332+
}
333+
323334
public boolean isChildren() {
324335
return isChildren;
325336
}
@@ -345,6 +356,10 @@ public String toString() {
345356
if (this.getNestedPath() != null) {
346357
result += "on path:" + this.getNestedPath() + " ";
347358
}
359+
360+
if (this.getInnerHits() != null) {
361+
result += "inner_hits:" + this.getInnerHits() + " ";
362+
}
348363
} else if (this.isChildren()) {
349364
result = "children condition ";
350365

src/main/java/org/nlpcn/es4sql/parse/NestedType.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public class NestedType {
2121
private boolean reverse;
2222
private boolean simple;
2323

24+
private String innerHits;
25+
2426
public boolean tryFillFromExpr(SQLExpr expr) throws SqlParseException {
2527
if (!(expr instanceof SQLMethodInvokeExpr)) return false;
2628
SQLMethodInvokeExpr method = (SQLMethodInvokeExpr) expr;
@@ -30,12 +32,18 @@ public boolean tryFillFromExpr(SQLExpr expr) throws SqlParseException {
3032
reverse = methodNameLower.equals("reverse_nested");
3133

3234
List<SQLExpr> parameters = method.getParameters();
33-
if (parameters.size() != 2 && parameters.size() != 1)
34-
throw new SqlParseException("on nested object only allowed 2 parameters (field,path)/(path,conditions..) or 1 parameter (field) ");
35+
int size = parameters.size();
36+
if (size != 3 && size != 2 && size != 1)
37+
throw new SqlParseException("on nested object only allowed 3 parameters (path,conditions..,inner_hits) or 2 parameters (field,path)/(path,conditions..) or 1 parameter (field) ");
38+
39+
// inner_hits
40+
if (size == 3) {
41+
this.innerHits = Util.extendedToString(parameters.remove(--size));
42+
}
3543

3644
String field = Util.extendedToString(parameters.get(0));
3745
this.field = field;
38-
if (parameters.size() == 1) {
46+
if (size == 1) {
3947
//calc path myself..
4048
if (!field.contains(".")) {
4149
if (!reverse)
@@ -51,7 +59,7 @@ public boolean tryFillFromExpr(SQLExpr expr) throws SqlParseException {
5159

5260
}
5361

54-
} else if (parameters.size() == 2) {
62+
} else if (size == 2) {
5563
SQLExpr secondParameter = parameters.get(1);
5664
if(secondParameter instanceof SQLTextLiteralExpr || secondParameter instanceof SQLIdentifierExpr || secondParameter instanceof SQLPropertyExpr) {
5765

@@ -83,4 +91,12 @@ public boolean isSimple() {
8391
public boolean isReverse() {
8492
return reverse;
8593
}
94+
95+
public String getInnerHits() {
96+
return innerHits;
97+
}
98+
99+
public void setInnerHits(String innerHits) {
100+
this.innerHits = innerHits;
101+
}
86102
}

src/main/java/org/nlpcn/es4sql/parse/WhereParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ else if (isChildren)
390390
throw new SqlParseException("could not fill nested from expr:" + expr);
391391
}
392392

393-
Condition condition = new Condition(Where.CONN.valueOf(opear), nestedType.path, null, methodName.toUpperCase(), nestedType.where, null);
393+
Condition condition = new Condition(Where.CONN.valueOf(opear), nestedType.path, null, methodName.toUpperCase(), nestedType.where, null, nestedType);
394394

395395
where.addWhere(condition);
396396
} else if (methodName.toLowerCase().equals("children")) {

src/main/java/org/nlpcn/es4sql/query/maker/QueryMaker.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
package org.nlpcn.es4sql.query.maker;
22

3-
3+
import com.fasterxml.jackson.core.JsonFactory;
44
import org.apache.lucene.search.join.ScoreMode;
5-
import org.elasticsearch.index.query.BoolQueryBuilder;
6-
import org.elasticsearch.index.query.QueryBuilder;
7-
import org.elasticsearch.index.query.QueryBuilders;
5+
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
6+
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
7+
import org.elasticsearch.common.xcontent.json.JsonXContentParser;
8+
import org.elasticsearch.index.query.*;
89
import org.elasticsearch.join.query.JoinQueryBuilders;
910
import org.nlpcn.es4sql.domain.Condition;
1011
import org.nlpcn.es4sql.domain.Where;
1112
import org.nlpcn.es4sql.domain.Where.CONN;
1213
import org.nlpcn.es4sql.exception.SqlParseException;
1314

15+
import java.io.IOException;
16+
1417
public class QueryMaker extends Maker {
1518

1619
/**
@@ -64,13 +67,29 @@ private void addSubQuery(BoolQueryBuilder boolQuery, Where where, QueryBuilder s
6467
Condition condition = (Condition) where;
6568

6669
if (condition.isNested()) {
70+
InnerHitBuilder ihb = null;
71+
if (condition.getInnerHits() != null) {
72+
try (JsonXContentParser parser = new JsonXContentParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, new JsonFactory().createParser(condition.getInnerHits()))) {
73+
ihb = InnerHitBuilder.fromXContent(parser);
74+
} catch (IOException e) {
75+
throw new IllegalArgumentException("couldn't parse inner_hits: " + e.getMessage(), e);
76+
}
77+
}
78+
6779
// bugfix #628
6880
if ("missing".equalsIgnoreCase(String.valueOf(condition.getValue())) && (condition.getOpear() == Condition.OPEAR.IS || condition.getOpear() == Condition.OPEAR.EQ)) {
69-
boolQuery.mustNot(QueryBuilders.nestedQuery(condition.getNestedPath(), QueryBuilders.boolQuery().mustNot(subQuery), ScoreMode.None));
81+
NestedQueryBuilder q = QueryBuilders.nestedQuery(condition.getNestedPath(), QueryBuilders.boolQuery().mustNot(subQuery), ScoreMode.None);
82+
if (ihb != null) {
83+
q.innerHit(ihb);
84+
}
85+
boolQuery.mustNot(q);
7086
return;
7187
}
7288

7389
subQuery = QueryBuilders.nestedQuery(condition.getNestedPath(), subQuery, ScoreMode.None);
90+
if (ihb != null) {
91+
((NestedQueryBuilder) subQuery).innerHit(ihb);
92+
}
7493
} else if(condition.isChildren()) {
7594
subQuery = JoinQueryBuilders.hasChildQuery(condition.getChildType(), subQuery, ScoreMode.None);
7695
}

src/test/java/org/nlpcn/es4sql/SqlParserTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,11 +814,11 @@ public void likeTestWithEscaped() throws SqlParseException {
814814

815815
@Test
816816
public void complexNestedAndOtherQuery() throws SqlParseException {
817-
String query = "select * from x where nested('path',path.x=3) and y=3";
817+
String query = "select * from x where nested('path',path.x=3,'{\"from\":0}') and y=3";
818818
Select select = parser.parseSelect((SQLQueryExpr) queryToExpr(query));
819819
LinkedList<Where> wheres = select.getWhere().getWheres();
820820
Assert.assertEquals(2, wheres.size());
821-
Assert.assertEquals("AND path NESTED_COMPLEX AND ( AND path.x EQ 3 ) ", wheres.get(0).toString());
821+
Assert.assertEquals("nested condition on path:path inner_hits:{\"from\":0} AND path NESTED_COMPLEX AND ( AND path.x EQ 3 ) ", wheres.get(0).toString());
822822
Assert.assertEquals("AND y EQ 3", wheres.get(1).toString());
823823
}
824824

0 commit comments

Comments
 (0)