0

Ive setted up elasticsearch with a NodeJS Server and need a working boolean query that checks different conditions in the search. How to do that?

I am using mongoosastic(query DSL) with NodeJS and the following query to get the results

mapping Function

async function mapMongoToElastic() {
return new Promise((resolve, reject) => {
console.log("---------Mapping gets created---------");
Product.createMapping(
  {
    mappings: {
      product: {
        properties: {
          ArtNumber: { type: "text" },
          Title: {
            type: "text",
            fields: {
              keyword: {
                type: "keyword"
              }
            }
          },
          DisplayPrice: { type: "double" },
          CF_Deliverytime: { type: "text" },
          Description_Short: { type: "text" },
          MainCat: {
            type: "text",
            fields: {
              keyword: {
                type: "keyword"
              }
            }
          },
          ItemCat: {
            type: "text",
            fields: {
              keyword: {
                type: "keyword"
              }
            }
          },
          Deeplink1: { type: "text" },
          Img_url: { type: "text" },
          CF_img_url2: { type: "text" },
          CF_img_url3: { type: "text" },
          CF_Availability: { type: "text" },
          CF_Productrating: {
            type: "text",
            fields: {
              keyword: {
                type: "keyword"
              }
            }
          },
          CF_Discount: {
            type: "text",
            fields: {
              keyword: {
                type: "keyword"
              }
            }
          },
          Shop: {
            type: "text",
            fields: {
              keyword: {
                type: "keyword"
              }
            }
          }
        }
      }
    }
  },
  function(err, mapping) {
    if (err) {
      console.log("error creating mapping (you can safely ignore this)");
      console.log(err);
      resolve(err);
    } else {
      console.log("X - ElasticSearch Mapping Created");
      resolve(mapping);
    }
   }
   );
  });
 }

Query function

async function asyncSearchWithOutFilter(query, from, to) {
return new Promise((resolve, reject) => {
Product.esSearch(
  {
    from: from,
    size: to,
    query: {
      multi_match: { 
        query: query.suche,
        fields: [ "Title^10", "ItemCat^5" ]
      }
    },
    aggs: {
      mainCats: {
        terms: { field: "MainCat.keyword" }
      },
      itemCats: {
        terms: { field: "ItemCat.keyword" }
      },
      itemShops: {
        terms: {
          field: "Shop.keyword"
        }
      }
    }
  },
  {},
  async (err, results) => {
    if (err) throw err;
    let res = await results;

    /*  console.log("-------------Total Hits---------------");
    console.log(res.hits.total);
    console.log("-----------------------------------------");
    console.log("-------------Shops---------------");
    console.log(res.aggregations.itemShops.buckets);
    console.log("-----------------------------------------");
    console.log("-------------Item-Categories---------------");
    console.log(res.aggregations.itemCats.buckets);
    console.log("-----------------------------------------"); */
    resolve(res);
  }
);
  });
 }

Expected results: - Query for "TV"

Results: Products with Title "TV" in - if Category has "TV" also, rank it up higher.

Problem: Smart-TV-Controller is also listed if searched for "TV", but not expected if someone is searching for a "TV"

help appreciated.

1 Answers1

0

Seems like you are trying to get exact match. You already have keyword type sub-field for both the fields Title and ItemCat. So instead use keyword field in match query.

query: {
  multi_match: { 
    query: query.suche,
    fields: [ "Title.keyword^10", "ItemCat.keyword^5" ]
  }
}

If you are not looking for exact match in Title then another way can be to set fields as below:

fields: [ "Title^10", "ItemCat.keyword^5" ]
Nishant
  • 7,504
  • 1
  • 21
  • 34
  • thanks for your answer. ive used the multi_match in the past and changed to the exact match. the problem with keywords is, that exact match has to happen, right? it works for the tv but doesnt works for the "smart tv" phrase then or am i wrong? – Cypress Hill Jan 22 '19 at 08:01
  • So you need partial match in both `Title` as well as `ItemCat`? – Nishant Jan 22 '19 at 14:48
  • yes, if `Title` and `ItemCat` is matched, it should rank higher than only match for `Title` – Cypress Hill Jan 22 '19 at 14:50
  • This can be achieved by giving same score to both `Title` and `ItemCat`. – Nishant Jan 22 '19 at 14:53
  • Good point, thanks for this hint. But what if the search query is only partial in ItemCat ? i.e. Search for "Samsung TV" - Match in Title but there is only a ItemCat called "TV" and not "Samsung TV". i hope this makes sense – Cypress Hill Jan 22 '19 at 14:59