1

I need to return a scored list of posts that contain as many tags that user provided as possible. Tags are stored in arrays as objects and user request contains an array of tag IDs (eg. ["a", "c"]). Single document looks something like this:

{
  id: 1,
  meta: {
    tags: [{id: "a", name: "Engine"}, {id: "b", name: "Street"}, {id: "c", name: "Sport"}]
  }
}

Sadly, term query returns posts in almost random order, as all of them have score 1.0:

{
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "meta.tags.id.keyword": [
             "a", "c"
            ]
          }
        }
      ]
    }
  }
}

I assume that thing would be quite easy if all tags would be in a single string, as this would be normal full text search, but how to achieve something like this for object arrays?

Here is a mapping exception (dynamically created by NEST client):

"mappings" : {
  "properties" : {
    "categories" : {
      "properties" : {
        "id" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    },
    "description" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "id" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "inFavourite" : {
      "type" : "long"
    },
    "likes" : {
      "type" : "long"
    },
    "name" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "photoPath" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "meta" : {
      "properties" : {
        "tags" : {
          "properties" : {
            "id" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "name" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
          }
        },
      }
    },
    "userId" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "viewCounter" : {
      "type" : "long"
    }
  }
}
2
  • Good question, would you mind sharing your index mapping, few sample and expected docs, so that its easy for community to reproduce your issue and provide working solution on your data-set. Commented Feb 7, 2021 at 3:50
  • I hava added a mapping. Docs are quite big, so it would be probably better to work on some custom examples. Commented Feb 7, 2021 at 9:01

1 Answer 1

1
{
  "query": {
    "function_score": {
      "query": { "match_all": {} },
      "boost": "5", 
      "functions": [
        {
          "filter": { "match": { "test": "bar" } },
          "random_score": {}, 
          "weight": 23
        },
        {
          "filter": { "match": { "test": "cat" } },
          "weight": 42
        }
      ],
      "max_boost": 42,
      "score_mode": "max",
      "boost_mode": "multiply",
      "min_score": 42
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.