You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mongo查询改造:如何在Map类型names字段中搜索字符串?

Searching Across Multi-Language Names Map in Spring Data MongoDB

Hey there! Since your Shop entity's name field is now a Map<String, String> for multi-language support, we need to adjust the MongoDB query to check all values in that map for your search keyword. Here's the modified solution:

Updated Query Method

Replace your existing findByName method with this one:

@RestResource(path = "searchByName")
@Query("{'$and': [{'companyId': ?0}, {'$expr': {'$anyElementTrue': {'$map': {'input': {'$objectToArray': '$names'}, 'as': 'nameEntry', 'in': {'$regex': ['$$nameEntry.v', ?1, 'i']}}}}]}")
Page<Shop> findByName(String companyId, String name, Pageable pageable);

Let's Break Down What This Does

I know that query looks a bit complex, so let's unpack it step by step:

  • $objectToArray: '$names': Converts your names map into an array of key-value pairs. For example, {"EN": "Shop1", "SW": "affär"} becomes [{"k":"EN", "v":"Shop1"}, {"k":"SW", "v":"affär"}] — this lets us iterate over all the name values.
  • $map: Loops through each entry in the converted array. We alias each entry as nameEntry.
  • $regex: ['$$nameEntry.v', ?1, 'i']: Checks if the value of the current entry ($$nameEntry.v) matches your search keyword (?1). The 'i' option makes the match case-insensitive, just like your original query.
  • $anyElementTrue: Returns true if any of the name values in the map match the keyword. This ensures we grab any Shop where at least one language's name contains your search term.
  • We keep the original companyId: ?0 filter to restrict results to the specified company, just like before.

Performance Tip (Important!)

If you're dealing with a large number of Shop documents, regular expression searches across map values can get slow. To speed things up, add a text index to your names field:

import org.springframework.data.mongodb.core.index.TextIndexed;

// Inside your Shop class
@TextIndexed
private Map<String, String> names;

With this index, you can use MongoDB's text search feature for faster, natural-language style searches. Here's the simplified query for that approach:

@RestResource(path = "searchByName")
@Query("{'$and': [{'companyId': ?0}, {'$text': {'$search': ?1}}]}")
Page<Shop> findByName(String companyId, String name, Pageable pageable);

Note: Text search works best for full-word matches or natural language queries. If you need prefix matching (like searching for 'sho' to find 'Shop1'), stick with the regex-based query we started with.

Example Test Case

If you search for 'sho', the query will match any Shop where names has a value like Shop1 (EN), Shoppee (JP), etc. Similarly, searching for 'aff' will pick up entries with affär (SW) or affiliate (EN).

内容的提问来源于stack exchange,提问作者Sandeepa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 12:02:40