嵌套类型查询

NestedQuery用于查询嵌套类型字段中子行的数据。嵌套类型不能直接查询,需要通过NestedQuery包装,NestedQuery中需要指定嵌套类型字段的路径和一个子查询,其中子查询可以是任意Query类型。

前提条件

参数

参数

说明

TableName

数据表名称。

IndexName

多元索引名称。

Path

路径名,嵌套类型的列的树状路径。例如news.title表示嵌套类型的news列中的title子列。

Query

嵌套类型的列中子列上的查询,子列上的查询可以是任意Query类型。

ScoreMode

当列存在多个值时基于哪个值计算分数。

InnerHits

嵌套类型字段的子列的配置参数。包括如下配置项:

  • Sort:Nested子行返回时的排序规则。

  • Offset:当Nested列包含多个子行时,子行返回的起始位置。

  • Limit:当Nested列包含多个子行时,返回子行的数量。默认值为3。

  • Highlight:Nested子列高亮参数配置。具体参数配置说明请参见摘要与高亮

示例

单层级嵌套类型查询示例

以下示例用于查询col_nested.nested_1tablestore的数据。其中col_nested为嵌套类型字段,子行中包含nested_1nested_2两列。

func NestedQuery(client *tablestore.TableStoreClient, tableName string, indexName string) {
    searchRequest := &tablestore.SearchRequest{}
    searchRequest.SetTableName(tableName)
    searchRequest.SetIndexName(indexName)
    query := &search.NestedQuery{ //设置查询类型为NestedQuery。
        Path: "col_nested", //设置嵌套类型字段的路径。
        Query: &search.TermQuery{ //构造NestedQuery的子查询。
            FieldName: "col_nested.nested_1", //设置字段名,注意带有Nested列的前缀。
            Term:      "tablestore",          //设置要查询的值。
        },
        ScoreMode: search.ScoreMode_Avg,
    }
    searchQuery := search.NewSearchQuery()
    searchQuery.SetQuery(query)
    searchRequest.SetSearchQuery(searchQuery)
    //设置为返回所有列。
    searchRequest.SetColumnsToGet(&tablestore.ColumnsToGet{
        ReturnAll: true,
    })
    searchResponse, err := client.Search(searchRequest)
    if err != nil {
        fmt.Printf("%#v", err)
        return
    }
    fmt.Println("IsAllSuccess: ", searchResponse.IsAllSuccess) //查看返回结果是否完整。
    fmt.Println("RowCount: ", len(searchResponse.Rows))
    for _, row := range searchResponse.Rows {
        jsonBody, err := json.Marshal(row)
        if err != nil {
            panic(err)
        }
        fmt.Println("Row: ", string(jsonBody))
    }
}

嵌套类型查询使用查询摘要与高亮示例

以下示例用于查询表中col_nested嵌套类型字段中nested_1子列的值能够匹配tablestore的数据,并在返回结果中对查询词进行高亮显示。其中col_nested嵌套类型字段的子行中包含nested_1nested_2两列。

func NestedQueryWithHighlight(client *tablestore.TableStoreClient, tableName string, indexName string) {
	searchRequest := &tablestore.SearchRequest{}
	searchRequest.SetTableName(tableName)
	searchRequest.SetIndexName(indexName)
	query := &search.NestedQuery{ //设置查询类型为NestedQuery。
		Path: "col_nested", //设置嵌套类型字段的路径。
		Query: &search.TermQuery{ //构造NestedQuery的子查询。
			FieldName: "col_nested.nested_1",       //设置字段名,注意带有Nested列的前缀。
			Term:      "tablestore", //设置要查询的值。
		},
		ScoreMode: search.ScoreMode_Avg,
		InnerHits: &search.InnerHits{
			Offset: proto.Int32(0),
			Limit:  proto.Int32(3),
			Highlight: &search.Highlight{
				FieldHighlightParameters: map[string]*search.HighlightParameter{
					"col_nested.nested_1": {
						NumberOfFragments: proto.Int32(5),
						PreTag:            proto.String("<em>"),
						PostTag:           proto.String("</em>"),
					},
				},
			},
		},
	}
	searchQuery := search.NewSearchQuery()
	searchQuery.SetQuery(query)
	searchRequest.SetSearchQuery(searchQuery)
	//设置为返回所有列。
	searchRequest.SetColumnsToGet(&tablestore.ColumnsToGet{
		ReturnAllFromIndex: true,
	})

	if resp, err := client.Search(searchRequest); err != nil {
		fmt.Println("Highlighting query failed with err: ", err)
	} else {
		fmt.Println("RequestId: " + resp.RequestId)
                // 打印高亮结果。
		printSearchHit(resp.SearchHits, " ")
	}
	fmt.Println("highlight query finished")
}


/**
 * 打印searchHit内容。
 * @param searchHits searchHits
 * @param padding Nested结构输出时,增加前缀以打印层次信息。
 */
func printSearchHit(searchHits []*tablestore.SearchHit, padding string) {
	for _, searchHit := range searchHits {
		if searchHit.Score != nil {
			fmt.Printf("%sScore: %f\n", padding, *searchHit.Score)
		}

		if searchHit.NestedDocOffset != nil {
			fmt.Printf("%sOffset: %d\n", padding, *searchHit.NestedDocOffset)
		}

		if searchHit.Row != nil {
			fmt.Printf("%sRow: %v\n", padding, *searchHit.Row)
		}

		if searchHit.HighlightResultItem != nil && len(searchHit.HighlightResultItem.HighlightFields) != 0 {
			fmt.Printf("%sHighlight: \n", padding)
			for colName, highlightResult := range searchHit.HighlightResultItem.HighlightFields {
				fmt.Printf("%sColumnName: %s, Highlight_Fragments: %v\n", padding+padding, colName, highlightResult.Fragments)
			}
		}

		if searchHit.SearchInnerHits != nil && len(searchHit.SearchInnerHits) != 0 {
			fmt.Printf("%sInnerHits: \n", padding)
			for path, innerSearchHit := range searchHit.SearchInnerHits {
				fmt.Printf("%sPath: %s\n", padding+padding, path)
				fmt.Printf("%sSearchHit: \n", padding+padding)
				printSearchHit(innerSearchHit.SearchHits, padding+padding)
			}
		}

		fmt.Println("")
	}
}

常见问题

相关文档