提前的 Elasticsearch Golang

huangapple go评论127阅读模式
英文:

advance elasticsearch golang

问题

我在我的聊天应用程序中执行了一般搜索,用户可以搜索消息或文件,使用go-elasticsearch包可以正常工作。为此,我根据一般搜索的要求创建了映射,例如对于messages,如下所示:
提前的 Elasticsearch Golang
对于文件,我创建了以下映射:
提前的 Elasticsearch Golang
对于ELS的搜索查询,我在两个字段上设置了条件,例如对于message搜索,使用了message.termmessage.channelid,对于file搜索查询,使用了file.namefile.channelid这两个字段。但是现在我想要执行高级的消息搜索和文件搜索。如何使用Elasticsearch创建高级消息搜索和高级文件搜索的搜索查询或搜索逻辑呢?我已经附上了所需的高级搜索字段的屏幕截图。
即:
提前的 Elasticsearch Golang
提前的 Elasticsearch Golang
提前的 Elasticsearch Golang

我想要执行高级的消息搜索和文件搜索。如何使用Elasticsearch创建高级消息搜索和高级文件搜索的搜索查询或搜索逻辑呢?我已经附上了所需的高级搜索字段的屏幕截图。
即:
提前的 Elasticsearch Golang
提前的 Elasticsearch Golang
提前的 Elasticsearch Golang

英文:

I have performed general search in my chat application where a user can search message or file, it work fine using go-elasticsearch package.For it I created mapping according to requirements of general search like this for messages. i.e.
提前的 Elasticsearch Golang
and for files I have created following mapping
提前的 Elasticsearch Golang
and for search query of ELS I put condition on two fields like for message search message.term AND message.channelid , for file search query used two fields file.name AND file.channelid. But now I want to perform advance elastic search for message and file search. How can I create search query or search logic for advance message search and advance file search using elastic search. I have attached screenshot for both advance search required field.
i.e.
提前的 Elasticsearch Golang
提前的 Elasticsearch Golang
提前的 Elasticsearch Golang

I want to perform advance elastic search for message and file search. How can I create search query or search logic for advance message search and advance file search using elastic search. I have attached screenshot for both advance search required field.
i.e.
提前的 Elasticsearch Golang
提前的 Elasticsearch Golang
提前的 Elasticsearch Golang

答案1

得分: 1

一种方法是使用Query string querySimple string query。您可以使用过滤器、引号和排除项。

另一种方法是将过滤参数转换为应用程序中的Elasticsearch查询。

以下是使用简单字符串查询和结构参数构建高级搜索查询的示例代码(使用Go语言)!

import (
    "encoding/json"
    "github.com/elastic/go-elasticsearch/v8/typedapi/core/search"
    "github.com/elastic/go-elasticsearch/v8/typedapi/types"
    "github.com/elastic/go-elasticsearch/v8/typedapi/types/enums/simplequerystringflag"
)

type MessageSearchParams struct {
    Query   string
    Filters *MessageSearchFilters
    Size    int
}

type MessageSearchFilters struct {
    UserIDs      []string
    ChannelIDs   []string
    MinCreatedAt time.Time
    MaxCreatedAt time.Time
}

func buildMessageSearchQuery(params *MessageSearchParams) (json.RawMessage, error) {
    // 在这里构建Elasticsearch查询
    var filters []types.QueryContainer
    if len(params.Filters.ChannelIDs) > 0 {
        filters = append(filters, types.QueryContainer{
            Terms: &types.TermsQuery{
                TermsQuery: map[types.Field]types.TermsQueryField{
                    "channel_id": params.Filters.ChannelIDs,
                },
            },
        })
    }
    if !params.Filters.MinCreatedAt.IsZero()  || !params.Filters.MaxCreatedAt.IsZero() {
        var gt, lt *types.DateMath
        if !params.Filters.MinCreatedAt.IsZero() {
            minCreatedAtStr := types.DateMath(strconv.FormatInt(params.Filters.MinCreatedAt.UnixMilli(), 10))
            gt = &minCreatedAtStr
        }
        if !params.Filters.MaxCreatedAt.IsZero() {
            maxCreatedAtStr := types.DateMath(strconv.FormatInt(params.Filters.MaxCreatedAt.UnixMilli(), 10))
            lt = &maxCreatedAtStr
        }
        filters = append(filters, types.QueryContainer{
            Range: map[types.Field]types.RangeQuery{
                "created_at": types.DateRangeQuery{
                    Gt: gt,
                    Lt: lt,
                },
            },
        })
    }

    queryStringFlag := types.NewSimpleQueryStringFlagsBuilder().
        SimpleQueryStringFlag(simplequerystringflag.PHRASE).
        SimpleQueryStringFlag(simplequerystringflag.NOT).
        Build()
    req := &search.Request{
        Query: &types.QueryContainer{
            Bool: &types.BoolQuery{
                Must: []types.QueryContainer{
                    {
                        SimpleQueryString: &types.SimpleQueryStringQuery{
                            Query: params.Query,
                            Flags: &queryStringFlag,
                        },
                    },
                },
                Filter: filters,
            },
        },
    }

    return json.Marshal(req)
}

上面的示例使用了typed api,但在Go语言中还有多种动态构建查询的方法。

英文:

One way would be to use Query string query or Simple string query. You can use filters, quotes, and excluding terms.

Another way would be converting the filter params to Elasticsearch query on application.

This is an example code to build query using simple string query and struct params to build advanced search query in Go!

import (
    "encoding/json"
	"github.com/elastic/go-elasticsearch/v8/typedapi/core/search"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types/enums/simplequerystringflag"
)

type MessageSearchParams struct {
	Query   string
	Filters *MessageSearchFilters
	Size    int
}

type MessageSearchFilters struct {
	UserIDs      []string
	ChannelIDs   []string
	MinCreatedAt time.Time
	MaxCreatedAt time.Time
}

func buildMessageSearchQuery(params *MessageSearchParams) (json.RawMessage, error) {
	// build elasticsearch query here
	var filters []types.QueryContainer
	if len(params.Filters.ChannelIDs) > 0 {
		filters = append(filters, types.QueryContainer{
			Terms: &types.TermsQuery{
				TermsQuery: map[types.Field]types.TermsQueryField{
					"channel_id": params.Filters.ChannelIDs,
				},
			},
		})
	}
	if !params.Filters.MinCreatedAt.IsZero()  || !params.Filters.MaxCreatedAt.IsZero() {
		var gt, lt *types.DateMath
		if !params.Filters.MinCreatedAt.IsZero() {
			minCreatedAtStr := types.DateMath(strconv.FormatInt(params.Filters.MinCreatedAt.UnixMilli(), 10))
			gt = &minCreatedAtStr
		}
		if !params.Filters.MaxCreatedAt.IsZero() {
			maxCreatedAtStr := types.DateMath(strconv.FormatInt(params.Filters.MaxCreatedAt.UnixMilli(), 10))
			lt = &maxCreatedAtStr
		}
		filters = append(filters, types.QueryContainer{
			Range: map[types.Field]types.RangeQuery{
				"created_at": types.DateRangeQuery{
					Gt: gt,
					Lt: lt,
				},
			},
		})
	}

	queryStringFlag := types.NewSimpleQueryStringFlagsBuilder().
		SimpleQueryStringFlag(simplequerystringflag.PHRASE).
		SimpleQueryStringFlag(simplequerystringflag.NOT).
		Build()
	req := &search.Request{
		Query: &types.QueryContainer{
			Bool: &types.BoolQuery{
				Must: []types.QueryContainer{
					{
						SimpleQueryString: &types.SimpleQueryStringQuery{
							Query: params.Query,
							Flags: &queryStringFlag,
						},
					},
				},
				Filter: filters,
			},
		},
	}

	return json.Marshal(req)
}

The above example is with typed api but also there are multiple ways to build query dynamically in Go.

huangapple
  • 本文由 发表于 2023年1月16日 14:29:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75130852.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定