查询“标签”文档的最佳设计方法

时间:2012-04-30 04:24:37

标签: ravendb

我正在存储文档 - 每个文档都有一个'标签'集合 - 就像这样。标签是用户定义的,可以是任何纯文本。

{
  "FeedOwner": "4ca44f7d-b3e0-4831-b0c7-59fd9e5bd30d",
  "MessageBody": "blablabla",
  "Labels": [
    {
      "IsUser": false,
      "Text": "Mine"
    },
    {
      "IsUser": false,
      "Text": "Incomplete"
    }
  ],
  "CreationDate": "2012-04-30T15:35:20.8588704"
}

我需要允许用户查询任何标签组合,即

"Mine" OR "Incomplete"
"Incomplete" only
or
"Mine" AND NOT "Incomplete"

这导致Raven查询如下:

Query: (FeedOwner:25eb541c\-b04a\-4f08\-b468\-65714f259ac2) AND (Labels,
Text:Mine) AND (Labels,Text:Incomplete)

我意识到Raven会为以前没见过的查询生成一个“动态索引”。我可以看到,这可能导致很多索引。

使用Raven实现此功能的最佳方法是什么?

[编辑]

这是我的Linq,但是我收到了Raven的错误“All is not supported”

var result = from candidateAnnouncement in session.Query<FeedAnnouncement>()
where listOfRequiredLabels.All(
    requiredLabel => candidateAnnouncement.Labels.Any(
        candidateLabel => candidateLabel.Text == requiredLabel))
select candidateAnnouncement;

[编辑]

我有一个类似的问题,答案就解决了这两个问题:Raven query returns 0 results for collection contains

1 个答案:

答案 0 :(得分:0)

请注意,如果FeedOwner是您文档的唯一属性,则查询根本没有多大意义。在这种情况下,您应该使用标准linq到对象在客户端上执行此操作。

现在,鉴于FeedOwner不是唯一的,您的查询基本上是正确的。但是,根据您实际想要返回的内容,您可能需要创建一个静态索引:

如果您正在使用动态生成的索引,那么您将始终将文档作为返回值,并且无法获得与查询匹配的特定标签。如果这对你没问题,那么就采用这种方法让查询优化器完成它的工作(只有你有真的很多文件才能预先构建索引)。

在另一种情况下,如果要将实际标签用作查询结果,则必须预先构建一个简单的地图索引,其中包含您要查询的字段,在您的示例中,这将是FeedOwner和Text of每个标签。您必须在要从查询返回的字段上使用FieldStorage.Yes,因此请在标签的Text属性上启用它。但是,没有必要使用FeedOwner属性,因为它是实际文档的一部分,raven将作为任何查询结果的一部分提供给您。请参阅ravens文档,了解如何构建静态索引并使用字段存储。