# Match query does not find matches

**URL:** <https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157>\
**Category:** Runtime Framework\
**Tags:** server-framework\
**Created:** [December 3, 2021, 11:14am UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157 "2021-12-03T11:14:14Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![chakie](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/chakie/32/772_2.png) [@chakie](https://forum.heroiclabs.com/u/chakie)\
**Post date:** [December 3, 2021, 11:14am UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/1 "2021-12-03T11:14:14Z")

</div>

So I create matches manually instead of using the match maker. It seems the built in match maker is really slow and it gives me no insight into what it does and why it takes a long time.

Matches are created like this:

```go
	limit := 5
	authoritative := true
	label := ""
	minSize := 0 //matchMode.PlayersMin
	maxSize := 10 //matchMode.PlayersMax
	query := "+mode:" + strconv.Itoa(matchMode.Ident)
	matches, err := nk.MatchList(ctx, limit, authoritative, label, &minSize, &maxSize, query)
	if err != nil {
		log.Printf("failed to list matches: %v", err)
		return "", err
	}

	log.Printf("query '%s' found %d matches", query, len(matches))

	for _, match := range matches {
		log.Printf("found match: %v", match)
	}

	var matchId string

	if len(matches) == 0 {
		var params = map[string]interface{}{"mode": matchMode.Ident}
		if matchId, err = nk.MatchCreate(ctx, "xxx", params); err != nil {
			return "", err
		}
		log.Printf("created a new match: %s", matchId)
	} else {
		log.Printf("using old match")
		matchId = matches[0].MatchId
	}
    ...

```

A new match is created if there’s no old matching match. I see that our callbacks for setting up a match handler is created and the match loop starts to run, so the match seems to be valid and fine. The next time the same code is executed the query `+mode:X` where `X` is a number that basically indicates the exact number of players wanted. The created matches have that property set and the query requires it. However `MatchList` never finds anything matching. If I set the `query` to `""` it does find the existing match.

Is there something that I’ve fundamentally missed about how the queries and/or properties work? When using the match maker the same query does seem to find matches. The code above is pretty much copied from the docs, except that there’s a small bug as `MatchList` wants pointers for `&minSize, &maxSize`.

---

<div class="post-metadata">

**Author:** ![mofirouz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/mofirouz/32/1523_2.png) [@mofirouz](https://forum.heroiclabs.com/u/mofirouz)\
**Post date:** [December 3, 2021, 11:29am UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/2 "2021-12-03T11:29:28Z")

</div>

> It seems the built in match maker is really slow and it gives me no insight into what it does and why it takes a long time.

Have you look at updating the matchmaker settings to allow less time for matchmaking: [Heroic Labs Documentation | Configuration](https://heroiclabs.com/docs/nakama/getting-started/configuration/#matchmaker)

> Is there something that I’ve fundamentally missed about how the queries and/or properties work? When using the match maker the same query does seem to find matches. The code above is pretty much copied from the docs, except that there’s a small bug as `MatchList` wants pointers for `&minSize, &maxSize` .

How are you creating the Match (match handler) and how are you persisting the match label? Remember it must be a JSON literal object:

[https://heroiclabs.com/docs/nakama/concepts/server-authoritative-multiplayer/#match-label](https://heroiclabs.com/docs/nakama/concepts/server-authoritative-multiplayer/#match-label)

> > You can only use search queries if you use a JSON value for the match label. If you instead use a simple value (e.g. `"team-deathmatch"` ) you can only perform an exact match using the `label` parameter in the [Match Listings API](https://heroiclabs.com/docs/nakama/concepts/server-authoritative-multiplayer/#search-query).

---

<div class="post-metadata">

**Author:** ![chakie](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/chakie/32/772_2.png) [@chakie](https://forum.heroiclabs.com/u/chakie)\
**Post date:** [December 3, 2021, 11:37am UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/3 "2021-12-03T11:37:24Z")

</div>

I would say I don’t even query for the label as it’s set to `""`. So it should work? The docs for the match label don’t really say what it should be used for, other than that it’s a label. I’ve seen no reason to use it and thus use `""`. I assume this is a case where the docs could use some improvement.

The example here:  
[https://heroiclabs.com/docs/nakama/concepts/server-authoritative-multiplayer/#search-query](https://heroiclabs.com/docs/nakama/concepts/server-authoritative-multiplayer/#search-query)

does not use the label either. Our `MatchInit` handler sets up an own `MatchState` struct and returns that along with a tick rate of 10 and an empty label.

This is confusing.

---

<div class="post-metadata">

**Author:** ![mofirouz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/mofirouz/32/1523_2.png) [@mofirouz](https://forum.heroiclabs.com/u/mofirouz)\
**Post date:** [December 3, 2021, 11:43am UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/4 "2021-12-03T11:43:48Z")

</div>

Yep we ought to improve this section of docs (cc @Sean )

If you set the match label (in the match handler) to a non-json object (like what the examples have shown), then you can only do exact queries using the `label` field in the MatchListing API.

However, if you set the label to a JSON object in the match handler, then Nakama will index the label and make it ready for search, and you can use the `query` field in the MatchListing API.

---

<div class="post-metadata">

**Author:** ![chakie](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/chakie/32/772_2.png) [@chakie](https://forum.heroiclabs.com/u/chakie)\
**Post date:** [December 3, 2021, 11:59am UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/5 "2021-12-03T11:59:55Z")

</div>

Ok, so what is the purpose of the label? Is it only to enable queries on the properties? I mean, can I just set it to `"foo":42` and be done with it and then use the property queries to find matches?

---

<div class="post-metadata">

**Author:** ![chakie](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/chakie/32/772_2.png) [@chakie](https://forum.heroiclabs.com/u/chakie)\
**Post date:** [December 3, 2021, 12:07pm UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/6 "2021-12-03T12:07:45Z")

</div>

Hm, no, that doesn’t work.

```auto
2021/12/03 14:04:15.222594 match.go:58: MatchInit: match dfd432f5-65f8-4290-a53b-71d58aa548ec initialized, label: {"foo":42}
...
2021/12/03 14:04:17.374009 battle_api.go:61: query 'mode:2' found 0 matches

```

Note that `mode:2` is even optional, it should certainly have found the created match. Or is the label somehow significant for `MatchList` too? I leave it as empty in order to find matches with any label.

---

<div class="post-metadata">

**Author:** ![mofirouz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/mofirouz/32/1523_2.png) [@mofirouz](https://forum.heroiclabs.com/u/mofirouz)\
**Post date:** [December 3, 2021, 12:16pm UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/7 "2021-12-03T12:16:55Z")

</div>

> Ok, so what is the purpose of the label? Is it only to enable queries on the properties? I mean, can I just set it to `"foo":42` and be done with it and then use the property queries to find matches?

The purpose of the `label` field in the MatchListing API is to do exact query look up without indexing.

> Hm, no, that doesn’t work.

Your match label is `{"foo": 42}` whilst your query is `mode:2` - this will never match.

> Or is the label somehow significant for `MatchList` too

Yes the match label you set in the match handler directly affects the query you are performing in the MatchListing call.

---

<div class="post-metadata">

**Author:** ![chakie](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/chakie/32/772_2.png) [@chakie](https://forum.heroiclabs.com/u/chakie)\
**Post date:** [December 3, 2021, 12:17pm UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/8 "2021-12-03T12:17:21Z")

</div>

The example at:

[https://heroiclabs.com/docs/nakama/concepts/server-authoritative-multiplayer/#match-listings](https://heroiclabs.com/docs/nakama/concepts/server-authoritative-multiplayer/#match-listings)

Uses `label := "skill=100-150"` as an argument to `MatchList`. Does this mean that the label is also a form of query and this would list matches created with labels `skill:111` and `skill:142`?

---

<div class="post-metadata">

**Author:** ![mofirouz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/mofirouz/32/1523_2.png) [@mofirouz](https://forum.heroiclabs.com/u/mofirouz)\
**Post date:** [December 3, 2021, 12:19pm UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/9 "2021-12-03T12:19:43Z")

</div>

> Uses `label := "skill=100-150"` as an argument to `MatchList` . Does this mean that the label is also a form of query and this would list matches created with labels `skill:111` and `skill:142` ?

Yes if that label was not a string but a JSON literal like:

```auto
{"skill": 100}

```

Then you can use the `query` field in the MatchList API.

---

<div class="post-metadata">

**Author:** ![chakie](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/chakie/32/772_2.png) [@chakie](https://forum.heroiclabs.com/u/chakie)\
**Post date:** [December 3, 2021, 12:20pm UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/10 "2021-12-03T12:20:24Z")

</div>

Even more confusing… Isn’t my `query` parameter supposed to match things I set in the parameters for `MatchCreate`? Or are those parameters only for my own use? Let me test and see.

---

<div class="post-metadata">

**Author:** ![chakie](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/chakie/32/772_2.png) [@chakie](https://forum.heroiclabs.com/u/chakie)\
**Post date:** [December 3, 2021, 12:27pm UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/11 "2021-12-03T12:27:05Z")

</div>

So given a match set up in `MatchInit` with a label:

```auto
	label, err := json.Marshal(map[string]int{"mode": matchMode.Ident})

```

i.e. `{"mode":2}`, then what am I supposed to use with `MatchList` to find it?

```auto
	limit := 1
	authoritative := true
	label := ""
	minSize := 0  
	maxSize := 10
	query := "+mode:2"
	matches, err := nk.MatchList(ctx, limit, authoritative, label, &minSize, &maxSize, query)

```

Or does the `label` also be filled in with `+mode:2`? No wonder this is hard to get right, the docs really need some sweet love.

---

<div class="post-metadata">

**Author:** ![chakie](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/chakie/32/772_2.png) [@chakie](https://forum.heroiclabs.com/u/chakie)\
**Post date:** [December 3, 2021, 12:42pm UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/12 "2021-12-03T12:42:35Z")

</div>

AFAIK there are no “JSON literals” in Go, but I could be wrong here. The above `json.Marshal` should create the required JSON.

I feel so extremely stupid when I can’t grok how this is supposed to work. Granted, I’m far from the sharpest tool in the shed, but this shouldn’t be impossible.

---

<div class="post-metadata">

**Author:** ![chakie](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/chakie/32/772_2.png) [@chakie](https://forum.heroiclabs.com/u/chakie)\
**Post date:** [December 3, 2021, 1:21pm UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/13 "2021-12-03T13:21:56Z")

</div>

Aha, this seems to work:

```go
func (m *Match) MatchInit(ctx context.Context, ...) (interface{}, int, string) {

    ...
	tickRate := 10
	label := "{\"mode\":" + strconv.Itoa(matchMode.Ident) + "}"

	return state, tickRate, label
}

```

And then querying with:

```go
	limit := 1
	label := ""
	minSize := 0
	maxSize := 10
	query := "+label.mode:" + strconv.Itoa(matchMode.Ident)
	matches, err := nk.MatchList(ctx, limit, true, label, &minSize, &maxSize, query)

```

The key here was to return the label as a string from `MatchInit`, ignore `label` when searching and add `label.` to the query to make it target the label.

Thank you for the help!

---

<div class="post-metadata">

**Author:** ![mofirouz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/mofirouz/32/1523_2.png) [@mofirouz](https://forum.heroiclabs.com/u/mofirouz)\
**Post date:** [December 3, 2021, 2:00pm UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/14 "2021-12-03T14:00:45Z")

</div>

I’m glad that this has worked. I apologise for the misdirections in the docs, we will improve on this.

---

<div class="post-metadata">

**Author:** ![chakie](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/chakie/32/772_2.png) [@chakie](https://forum.heroiclabs.com/u/chakie)\
**Post date:** [December 3, 2021, 2:06pm UTC](https://forum.heroiclabs.com/t/match-query-does-not-find-matches/2157/15 "2021-12-03T14:06:56Z")

</div>

My role is to be confused about everything and find things that don’t make sense. 🙂
