如何在App Engine Datastore中查询特定数组长度的实体数量(Objectify)
Unfortunately, Google Cloud Datastore (which Objectify wraps) doesn’t support directly querying entities based on the length of an array property. The reason is that Datastore indexes array properties by expanding each element into a separate index entry—there’s no built-in index or operator to track the array’s length natively.
The standard solution here is to add a computed property to your entity that explicitly tracks the length of the array. You’ll need to maintain this property whenever the array is modified, then use it in your filter.
Step 1: Update Your Entity Class
Add an integer field to track the number of messages. Adjust the code below to match your actual messages structure (whether it’s a direct list of objects or nested under a values field):
import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Index; import java.util.List; @Entity public class Request { @Id private Long id; private String name; // Match your actual messages structure—here we assume a list of Message objects private List<Message> messages; // Computed property to track array length, indexed for querying @Index private int messageCount; // Default constructor required by Objectify public Request() {} // Getters and setters public void setMessages(List<Message> messages) { this.messages = messages; // Sync the count whenever the messages list is set this.messageCount = (messages != null) ? messages.size() : 0; } // If you modify the list in-place (e.g., add/remove elements), update the count manually public void addMessage(Message message) { this.messages.add(message); this.messageCount++; } // ... other getters/setters, plus your Message class definition }
If your messages property is an object containing a values array (like your example shows), adjust the setter to count messages.getValues().size() instead.
Step 2: Query Using the Computed Property
Once you’re keeping messageCount in sync with the actual array length, your query becomes simple:
int count = ofy().load().type(Request.class) .filter("messageCount", 2) // Filter for entities with exactly 2 messages .count();
Key Notes
- Always keep
messageCountsynchronized with the array length. If you modify the array in-place (without using the setter), remember to update the count manually. - Mark
messageCountwith@Indexso Objectify can create the necessary index for the query. - This approach works for exact matches and range queries alike (e.g.,
filter("messageCount >", 5)to find entities with more than 5 messages).
内容的提问来源于stack exchange,提问作者VitalyT

